From d68749d7bde7bfc55fc5ac2315fb551c8d9db667 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Fri, 17 Jan 2025 18:22:48 +0000 Subject: [PATCH] Squashed 'library/' changes from 78fc550584d..b102eb97611 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit b102eb97611 Rollup merge of #135003 - RalfJung:deprecate-allowed-through-unstable, r=davidtwco 09ccac89813 Rollup merge of #132654 - joboet:lazy_main, r=ChrisDenton 9a5f11b6bdc Auto merge of #135525 - jhpratt:rollup-4gu2wpm, r=jhpratt 808a28bb2e5 Rollup merge of #134678 - zachs18:offset-ptr-update, r=tgross35 038b55923da Rollup merge of #134338 - tgross35:overflowing-c-safe-ret, r=bjorn3,antoyo afb7906d983 Rollup merge of #134143 - nyurik:err-nul, r=dtolnay 09f7f735638 intrinsics: deprecate calling them via the unstable std::intrinsics path b1bab8efb30 Update ReadDir::next in std::sys::pal::unix::fs to use `&raw const (*ptr).field` instead of `ptr.offset(...).cast()`. 6b3eb0e11bc Update compiler-builtins to 0.1.143 c26fde2487d Rollup merge of #135423 - compiler-errors:enforce-const-trait-syntactical, r=oli-obk,RalfJung d4e61054fa0 Enforce syntactical stability of const traits in HIR 8cba3108c65 Update compiler-builtins to 0.1.141 72304171451 add comments explaining main thread identification de1528ca1d5 std: lazily allocate the main thread handle 7d65632251e Revert "Remove the Arc rt::init allocation for thread info" 1938ccffee3 Auto merge of #135473 - matthiaskrgr:rollup-ksnst4l, r=matthiaskrgr e57af4cc513 Rollup merge of #135381 - cod10129:vec-splice-doc, r=tgross35 4b1f813eb19 Auto merge of #135359 - RalfJung:lang-start-unwind, r=joboet 3a1522edb09 Auto merge of #135465 - jhpratt:rollup-7p93bct, r=jhpratt d68853badd5 Rollup merge of #135393 - Ayush1325:uefi-helper-path, r=thomcc 2583e5e939e Add another `Vec::splice` example e53c5c9c5db uefi: helpers: Introduce OwnedDevicePath f17b1628cec Rollup merge of #135405 - Ayush1325:path-is-absolute, r=tgross35 41ac367ffc7 path: Move is_absolute check to sys::path 44a9def9f39 Auto merge of #135420 - GuillaumeGomez:rollup-93vepka, r=GuillaumeGomez 242154d7a56 Auto merge of #135384 - saethlin:inline-copy-from-slice, r=joboet d76bc765c20 Update the explanation for why we use box_new in vec! a8314e3425d Auto merge of #135402 - matthiaskrgr:rollup-cz7hs13, r=matthiaskrgr 736f71506f1 Rollup merge of #135379 - steffahn:uniquerc-invariant, r=Mark-Simulacrum f1fd86b54fa Add inherent versions of MaybeUninit methods for slices 50cffd12adb Add #[inline] to copy_from_slice 221253c726d Auto merge of #135360 - RalfJung:structural-partial-eq, r=compiler-errors 8853a8d51d2 Make UniqueRc invariant for soundness 5c997f2acdc avoid nesting the user-defined main so deeply on the stack 1f09d97cbf0 use a single large catch_unwind in lang_start 3093827de07 update and clarify StructuralPartialEq docs e2f8a108b9a Rename `pos` to `position` c6dff32f287 Convert `struct FromBytesWithNulError` into enum e47fc56aa4a Rollup merge of #135347 - samueltardieu:push-qvyxtxsqyxyr, r=jhpratt d8923fc714a Rollup merge of #135324 - Ayush1325:uefi-fs-unsupported, r=joboet 9709d9bad5d Rollup merge of #135236 - scottmcm:more-mcp807-library-updates, r=ChrisDenton 849afc40e34 Improve the safety documentation on new_unchecked 2add857ca03 Use `NonNull::without_provenance` within the standard library 2764b7e14ab alloc: remove unsound `IsZero` for raw pointers c577821efe2 Rollup merge of #134693 - SpriteOvO:proc-macro-use-to-tokens-in-quote, r=tgross35 7dbc3bcab16 Rollup merge of #132607 - YohDeadfall:pthread-name-fn-with-result, r=tgross35 ab71837c330 Update a bunch of library types for MCP807 4052574937d Initial fs module for uefi 946c19e04cb Rollup merge of #134908 - madsmtm:ptr-from_ref-docs, r=ibraheemdev 01372432cbb Rollup merge of #134619 - hkBst:patch-7, r=jhpratt c22148b767f Fix `proc_macro::quote!` for raw ident c421c1a946a Append `TokenTree` with `ToTokens` in `proc_macro::quote!` c283b86cc76 Used pthread name functions returning result for FreeBSD and DragonFly 668cb10cba5 Auto merge of #135268 - pietroalbini:pa-bump-stage0, r=Mark-Simulacrum f3f0119335a Rollup merge of #135269 - estebank:unneeded-into, r=compiler-errors d7dd4a6bc58 Rollup merge of #135242 - RalfJung:nonnull-provenance, r=jhpratt a34edcbbb60 Remove some unnecessary `.into()` calls 661c077ae5b fmt 9d29620a31a update cfg(bootstrap) 60fa1562951 update version placeholders c0e33bf31ca add missing provenance APIs on NonNull 830ee4bb4d6 Rollup merge of #135176 - kornelski:env-example, r=cuviper 790735e2a6d Rollup merge of #134389 - rust-wasi-web:condvar-no-threads, r=m-ou-se b3fa835baa8 Rollup merge of #133057 - tisonkun:into-chars, r=Amanieu 3987eb22905 Avoid naming variables `str` 7c71ffcfa97 Rollup merge of #135139 - c410-f3r:8-years-rfc, r=jhpratt 6536ec2d9b0 Rollup merge of #131830 - hoodmane:emscripten-wasm-eh, r=workingjubilee e44be94c9eb More compelling env_clear() examples 5db91e58005 Rollup merge of #135153 - crystalstall:master, r=workingjubilee cb8cf0fa5d0 Add support for wasm exception handling to Emscripten target a1da07b21df chore: remove redundant words in comment b2b55f6bdae Rollup merge of #135111 - tgross35:float-doc-aliases, r=Noratrieb 0bd45849186 [generic_assert] Constify methods used by the formatting system c200a189c66 Rollup merge of #135121 - okaneco:const_slice_reverse, r=jhpratt e03872bb30a Mark `slice::reverse` unstably const 0e581b92097 Clarified the documentation on core::iter::from_fn and core::iter::successors 320482169fb Rollup merge of #135110 - matthiaskrgr:adler, r=workingjubilee e7ca1049aa7 Rollup merge of #135104 - the8472:disable-in-place-iter-for-flatten, r=Mark-Simulacrum 8ffc4e84463 Rollup merge of #134996 - bdbai:uwp-support, r=jieyouxu,ChrisDenton fee42729979 Add doc aliases for `libm` and IEEE names f4b33a3e46f library: fix adler{-> 2}.debug 2e05379f866 add regression test for unsound Flatten/FlatMap specialization 9467350f844 do not in-place-iterate over flatmap/flatten 6346a915b55 Rollup merge of #135091 - workingjubilee:backtrace-0.3.75, r=workingjubilee 3ef2891d388 Rollup merge of #135070 - klensy:backtrace-deps, r=workingjubilee 24366d36dce Rollup merge of #135046 - RalfJung:rustc_box_intrinsic, r=compiler-errors 307f559c6c4 Rollup merge of #133964 - joboet:select_unpredictable, r=tgross35 0b2fd26bdc8 Bump backtrace to 0.3.75 3d624d66f11 Rollup merge of #133420 - thesummer:rtems-unwind, r=workingjubilee 6137ccc52ac sync to actual dep verions of backtrace 318269a33f4 turn rustc_box into an intrinsic bd743cec036 Auto merge of #135059 - matthiaskrgr:rollup-0ka9o3h, r=matthiaskrgr e74ac082b32 Rollup merge of #134241 - liigo:patch-16, r=dtolnay 53e41a6a5a7 Auto merge of #134692 - GrigorenkoPV:sync_poision, r=tgross35 366ac34fa96 Fix UWP build cd6c49f49b5 Bump backtrace to rust-lang/backtrace-rs@4d7906b 98ee6c8c68c Auto merge of #122565 - Zoxc:atomic-panic-msg, r=the8472 ffaa2184220 path in detail aa0e6e8bd1a Move some things to `std::sync::poison` and reexport them in `std::sync` b8087f526a0 fix doc for missing Box allocator consistency 40434b2c26c Auto merge of #135005 - matthiaskrgr:rollup-5ubuitt, r=matthiaskrgr 32614550fb9 Rollup merge of #134985 - mgsloan:remove-unnecessary-qualification-in-Ord-trait-docs, r=Noratrieb d5f262cc53a Rename the internal simpler `quote` macro to `minimal_quote` 6c8e14169a9 Auto merge of #134080 - kleisauke:avoid-lfs64-emscripten, r=Noratrieb 33b4b03fe6a Try to write the panic message with a single `write_all` call 8795c3547eb std::fs::DirEntry.metadata(): prefer use of lstat() on Emscripten fb895251bd9 Avoid use of LFS64 symbols on Emscripten ed5888769c6 Auto merge of #134969 - Marcondiro:master, r=jhpratt,programmerjake c1b709541e2 Rollup merge of #131439 - mu001999-contrib:cleanup/static-mut, r=estebank 847cd898006 Remove qualification of `std::cmp::Ordering` in `Ord` doc e38fc1b0843 Auto merge of #132195 - clarfonthey:bigint-mul, r=scottmcm 4f7e5a623be Auto merge of #134966 - matthiaskrgr:rollup-lmhmgsv, r=matthiaskrgr aff952b674c char to_digit: avoid unnecessary casts to u64 9e0a6b0a3c4 Rollup merge of #134953 - DiuDiu777:unaligned-doc, r=RalfJung b003e5812c2 Auto merge of #134620 - ChrisDenton:line-writer, r=tgross35 8b8fd2d5855 Rollup merge of #134930 - RalfJung:ptr-docs-valid-access, r=jhpratt d487d12d362 Rollup merge of #134927 - DaniPopes:const-as_flattened_mut, r=scottmcm bfe0d0f6000 fix doc for read write unaligned in zst operation 99ca6ca7611 Auto merge of #134757 - RalfJung:const_swap, r=scottmcm 316349488dc ptr docs: make it clear that we are talking only about memory accesses b7b6a5d0649 Make slice::as_flattened_mut unstably const 0b1d0d95c67 Fix ptr::from_ref documentation example comment f26cc531ab6 Rollup merge of #134884 - calciumbe:patch1, r=jieyouxu b7620c7c1d9 Rollup merge of #134870 - geofft:patch-1, r=jhpratt 9adc4a11633 fix: typos f5e949debed Rollup merge of #134851 - lukas-code:alloc-ffi, r=tgross35 309cb6599b7 Fix sentence fragment in `pin` module docs d086afd99b8 docs: inline `alloc::ffi::c_str` types to `alloc::ffi` 15137457840 Auto merge of #134547 - SUPERCILEX:unify-copy, r=thomcc 5807d879643 Rollup merge of #134832 - tgross35:update-builtins, r=tgross35 c6c4ae7c842 Tidy up bigint mul methods a9e94810233 Rollup merge of #134823 - chloefeal:fix, r=tgross35,dtolnay 0e23de8b41d Update library/alloc/tests/sort/tests.rs c94032f1779 Update `compiler-builtins` to 0.1.140 a41400395c5 Rollup merge of #133663 - scottmcm:carrying_mul_add, r=Amanieu 764af3bad24 Override `carrying_mul_add` in cg_llvm 18ee1da10b9 Move `{widening, carrying}_mul` to an intrinsic with fallback MIR 559fdf03383 Fix typos acfeed3d3df Auto merge of #134822 - jieyouxu:rollup-5xuaq82, r=jieyouxu 5fb4df97165 Rollup merge of #134819 - ChrisDenton:trunc, r=Mark-Simulacrum 68b148643ac Rollup merge of #134622 - ChrisDenton:write-file-utf8, r=Mark-Simulacrum 6f23131fac2 Rollup merge of #134606 - RalfJung:ptr-copy-docs, r=Mark-Simulacrum e290e70bdc1 Auto merge of #134786 - ChrisDenton:fix-rename-symlink, r=tgross35 5cf455ff60d Fix renaming symlinks on Windows 0a3943e9496 Fix mistake in windows file open 051ece2a59c Rollup merge of #134791 - notriddle:notriddle/inline-ffi-error-types, r=tgross35 3a2ca84c46f Rollup merge of #134789 - betrusted-io:bump-unwinding-to-0.25.0, r=Mark-Simulacrum 3cbbd43963e Rollup merge of #134782 - wtlin1228:docs/iter-rposition, r=Mark-Simulacrum 1e8a843e7fd Rollup merge of #134728 - deltragon:barrier-doc, r=tgross35 9b632c12457 Rollup merge of #134649 - SUPERCILEX:statx-remember, r=thomcc a9b12533594 Rollup merge of #134644 - kpreid:duplicates, r=Mark-Simulacrum 7d72bc6894b Rollup merge of #134379 - bjoernager:slice-as-array, r=dtolnay c988c5c469a docs: inline `core::ffi::c_str` types to `core::ffi` f3a43e876b3 docs: inline `std::ffi::c_str` types to `std::ffi` ef9344328ea unwinding: bump version to fix asm b5a7e1cb2c3 Impl FromIterator for tuples with arity 1-12 97a492b242e Fix formatting 7bb71817d2d docs: update code example for Iterator#rposition 838b01dae5e stabilize const_alloc_layout 7c4bb0b875d rename typed_swap → typed_swap_nonoverlapping 3d7df0fa2cb stabilize const_swap adefdcb1aaf Auto merge of #134729 - oliveredget:typo, r=jieyouxu a76414742c2 Auto merge of #134722 - ChrisDenton:trunc, r=Amanieu 7102c61d871 Auto merge of #134333 - daxpedda:stdarch-bump, r=daxpedda 781fb68dbba Fix compilation issues on other unixes 2b6589fec62 Bump `stdarch` 301f4c8ba3f chore: fix typos b3642490a4a Use scoped threads in `std::sync::Barrier` examples efbda65a57a Windows: Use FILE_ALLOCATION_INFO for truncation 0429732714d Rollup merge of #134689 - RalfJung:ptr-swap-test, r=oli-obk f71f75d522a Rollup merge of #134662 - ionicmc-rs:any-safety-docs, r=Amanieu 6fc5a515b01 core: fix const ptr::swap_nonoverlapping when there are pointers at odd offsets in the type 2a7c4107dd3 Rollup merge of #134363 - estebank:derive-default, r=SparrowLii 6a41c5bd0cd Rollup merge of #134672 - Zalathar:revert-coverage-attr, r=wesleywiser 00523c6df55 Use `#[derive(Default)]` instead of manually implementing it 7a6c4cf81d9 Revert "Auto merge of #130766 - clarfonthey:stable-coverage-attribute, r=wesleywiser" 1d47e6a5af8 Auto merge of #134666 - matthiaskrgr:rollup-whe0chp, r=matthiaskrgr 47eacac789d Auto merge of #131311 - rust-lang:cargo_update, r=clubby789 08311d3b105 Rollup merge of #134642 - kpreid:pointerlike-cell, r=compiler-errors 49d33b15720 Rollup merge of #134583 - Enselic:maybe-uninit-transmute, r=workingjubilee ce16d167b68 Rollup merge of #130289 - intgr-forks:Permissions-readonly-vs-unix-root, r=ChrisDenton 5ec57233686 Fixes safety docs for `dyn Any + Send {+ Sync}` e31ed41f4ba Implement `PointerLike` for `isize`, `NonNull`, `Cell`, `UnsafeCell`, and `SyncUnsafeCell`. 736e842fc2a Auto merge of #134330 - scottmcm:no-more-rvalue-len, r=matthewjasper 1a45918d751 docs: Permissions.readonly() also ignores root user special permissions e15ef644395 Improve prose around `as_slice` example of IterMut d03b67c2429 Specify only that duplicates are discarded, not the order. e70cbb149f5 Auto merge of #131193 - EFanZh:asserts-vec-len, r=the8472 619365dce13 Delete `Rvalue::Len` f913021f500 docs: `transmute<&mut T, &mut MaybeUninit>` is unsound when exposed to safe code 0233b4ec888 Impl String::into_chars 56cc86af99f Rollup merge of #134602 - kpreid:pointerlike-doc, r=tgross35 9549c0c5306 Fix forgetting to save statx availability on success c50706f5f04 Auto merge of #134640 - matthiaskrgr:rollup-xlstm3o, r=matthiaskrgr 42621a94cbe Document collection `From` and `FromIterator` impls that drop duplicate keys. 22c6dcd7b19 Rollup merge of #134630 - fifty-six:master, r=workingjubilee 9c5420a144f Auto merge of #130733 - okaneco:is_ascii, r=scottmcm a5f05c31739 cargo update 88936d663d5 Eliminate redundant statx syscalls ae80bcc9736 Rollup merge of #134325 - theemathas:is_null-docs, r=RalfJung 37803ed66ad Rollup merge of #131072 - Fulgen301:windows-rename-posix-semantics, r=ChrisDenton 3edae543ffa Use `&raw` for `ptr` primitive docs 9f89bf55fb2 Unify fs::copy and io::copy 8f6317d2b8a Windows: Use WriteFile to write to a UTF-8 console dca1911ca13 Avoid short writes in LineWriter 10f58801c5e Document CTFE behavior of methods that call is_null 52c70cefc4e Correctly document is_null CTFE behavior. 8240334bbea ptr::copy: fix docs for the overlapping case 3d7ea928c48 Rollup merge of #134593 - kornelski:less-unwrap, r=jhpratt 8d44917bb2b Rollup merge of #134579 - hkBst:patch-6, r=jhpratt d1a3570e402 Rollup merge of #134577 - hkBst:patch-5, r=jhpratt 797d88a4f6e Rollup merge of #134576 - hkBst:patch-4, r=jhpratt 0d4f2977e8f Document `PointerLike` implementation restrictions. 39c036dacf9 Less unwrap() in documentation 9eacbacb845 Rollup merge of #123604 - michaelvanstraten:proc_thread_attribute_list, r=ChrisDenton 605e793d35f Rollup merge of #134573 - lukas-code:unimpl-dyn-pointerlike, r=compiler-errors 03b554d4296 Rollup merge of #134570 - hkBst:patch-3, r=joboet cb9fd5abb2d Rollup merge of #134560 - RalfJung:miri-thread-spawn, r=jhpratt 8ef4e1708c6 Improve prose around into_slice example of IterMut 490893e4337 Improve prose around `as_slice` example of Iter 346bb96231a Improve prose around basic examples of Iter and IterMut b2c67187209 remove reference to dangling from slice::Iter 8a76ac07549 fix `PointerLike` docs ea624faa800 unimplement `PointerLike` for trait objects 0348754b8e8 split up `#[rustc_deny_explicit_impl]` attribute 83961772930 mri: add track_caller to thread spawning methods for better backtraces 47c18d11c25 Rollup merge of #134518 - hltj:typo-fix, r=tgross35 a407b54ba53 Rollup merge of #132830 - wr7:substr_range_documentation, r=tgross35 1e42e55ad7f Rollup merge of #126118 - jan-ferdinand:docs_for_vec_set_len, r=the8472 325c2c83a7d fix typos in the example code in the doc comments of `Ipv4Addr::from_bits()`, `Ipv6Addr::from_bits()` & `Ipv6Addr::to_bits()` 2a30c761db7 build: Update libc version ff8e6c7266c Rollup merge of #134490 - hong9lol:typo, r=jhpratt 1ef2006c9ff Rollup merge of #132056 - weiznich:diagnostic_do_not_recommend_final_tests, r=compiler-errors 36dec866386 fix typo in ptr/mod.rs ba3898d82f3 Auto merge of #134443 - joshtriplett:use-field-init-shorthand, r=lqd,tgross35,nnethercote 815119ea508 Rollup merge of #134452 - jalil-salame:fix-lazy-cell-docs, r=tgross35 e5a64b47a53 Add 'into_array' conversion destructors for 'Box', 'Rc', and 'Arc'; 1e20f65b874 Implement Condvar::wait_timeout for targets without threads 0d4be900a97 Auto merge of #134425 - clubby789:cargo-update, r=jieyouxu e94636ef1eb fix(LazyCell): documentation of get[_mut] was wrong 9552b94e220 Stabilize `#[diagnostic::do_not_recommend]` 8f6473ca201 Use field init shorthand where possible 4dd1bd84b80 Rollup merge of #134426 - hkBst:patch-3, r=lqd 439ea50e256 Rollup merge of #133265 - the8472:extract-if-ranges, r=cuviper 5b50e4a613b compiler & tools dependencies: Updating allocator-api2 v0.2.20 -> v0.2.21 Updating annotate-snippets v0.11.4 -> v0.11.5 Updating anyhow v1.0.93 -> v1.0.94 Updating bstr v1.11.0 -> v1.11.1 Updating chrono v0.4.38 -> v0.4.39 Updating clap v4.5.21 -> v4.5.23 Updating clap_builder v4.5.21 -> v4.5.23 Updating clap_complete v4.5.38 -> v4.5.39 Updating clap_lex v0.7.3 -> v0.7.4 Updating colored v2.1.0 -> v2.2.0 Updating console v0.15.8 -> v0.15.10 Updating crossbeam-channel v0.5.13 -> v0.5.14 Updating crossbeam-deque v0.8.5 -> v0.8.6 Updating crossbeam-utils v0.8.20 -> v0.8.21 Updating encode_unicode v0.3.6 -> v1.0.0 Updating fastrand v2.2.0 -> v2.3.0 Updating home v0.5.9 -> v0.5.11 Updating js-sys v0.3.74 -> v0.3.76 Updating libc v0.2.167 -> v0.2.168 Updating miniz_oxide v0.8.0 -> v0.8.1 Updating pest v2.7.14 -> v2.7.15 Updating pest_derive v2.7.14 -> v2.7.15 Updating pest_generator v2.7.14 -> v2.7.15 Updating pest_meta v2.7.14 -> v2.7.15 Updating redox_syscall v0.5.7 -> v0.5.8 Updating rustc-stable-hash v0.1.0 -> v0.1.1 Updating rustix v0.38.41 -> v0.38.42 Updating self_cell v1.0.4 -> v1.1.0 Updating semver v1.0.23 -> v1.0.24 Updating serde v1.0.215 -> v1.0.216 Updating serde_derive v1.0.215 -> v1.0.216 Adding thiserror v2.0.7 Adding thiserror-impl v2.0.7 Updating time v0.3.36 -> v0.3.37 Updating time-macros v0.2.18 -> v0.2.19 Updating tokio v1.41.1 -> v1.42.0 Updating wasm-bindgen v0.2.97 -> v0.2.99 Updating wasm-bindgen-backend v0.2.97 -> v0.2.99 Updating wasm-bindgen-macro v0.2.97 -> v0.2.99 Updating wasm-bindgen-macro-support v0.2.97 -> v0.2.99 Updating wasm-bindgen-shared v0.2.97 -> v0.2.99 Updating wasm-encoder v0.221.0 -> v0.221.2 Updating wasmparser v0.221.0 -> v0.221.2 Updating wast v221.0.0 -> v221.0.2 Updating wat v1.221.0 -> v1.221.2 fbac32d2761 Auto merge of #130766 - clarfonthey:stable-coverage-attribute, r=wesleywiser f8d5f2f5031 Fix typo in uint_macros.rs 773ce8e12e0 Rollup merge of #134202 - nnethercote:rm-existing_doc_keyword, r=GuillaumeGomez 1ea6333e43b Remove `rustc::existing_doc_keyword` lint. 879b904eae9 Move `doc(keyword = "while")`. d655fd187d6 Stabilize #[coverage] attribute 7adb8ab561b remove obsolete comment and pub(super) visibility 71740c5e592 remove bounds from vec and linkedlist ExtractIf f5981cec754 Add a range argument to vec.extract_if f0297f13dde Rollup merge of #134277 - notriddle:notriddle/inline-into, r=GuillaumeGomez e88df256c16 Auto merge of #134332 - Zalathar:rollup-oe23hkw, r=Zalathar 93329f34b67 Rollup merge of #134310 - tkr-sh:master, r=Noratrieb ab4f84cae3e Rollup merge of #133406 - EFanZh:lock-value-accessors, r=Noratrieb 69756988c15 Rollup merge of #130361 - devnexen:sock_cloexec_solaris, r=cuviper 114f5e2c405 Auto merge of #133223 - zachs18:uniquerc-impls, r=Noratrieb cd6542897cb Asserts the maximum value that can be returned from `Vec::len` 9d2ca9a3477 Auto merge of #134258 - bjorn3:no_public_specialization, r=petrochenkov 66b6e751301 Rollup merge of #134022 - shahn:doc_clarify_extend_for_tuple_version, r=tgross35 3aa32597ed9 Rollup merge of #133986 - olishmollie:tracking-issue-127154-documentation, r=tgross35 b35e7babfbf Correct spelling of CURRENT_RUSTC_VERSION dca96f2d618 Replace i32 by char in `split_at` & `_unchecked` 5c0062fd6ba Add clarity to the "greater" of `VecDeque::insert` 36d2006d1e1 Replace i32 by char to add clarity f9d5fcf495e Auto merge of #134296 - matthiaskrgr:rollup-o0sxozj, r=matthiaskrgr 5416be5795f Add documentation for anonymous pipe module bd52a6d6b8d Rollup merge of #133942 - BD103:black-box-docs, r=saethlin 1d8c71769ac Rollup merge of #134255 - bjoernager:master, r=Noratrieb cd53ef86a04 Rollup merge of #134254 - hermit-os:hermit-c_char, r=workingjubilee feb218aac4a Rollup merge of #134252 - hermit-os:hermit-is_absolute, r=tgross35 78ef2d597d4 rustdoc-search: let From and Into be unboxed c1f85483921 Rollup merge of #134229 - purplesyringa:provenance-docs, r=saethlin d03fb91bd4d Rollup merge of #134140 - compiler-errors:unsafe-binders-ast, r=oli-obk c90e7e3ca98 Remove support for specializing ToString outside the standard library 1c55c9fbc60 Auto merge of #134047 - saethlin:inline-fmt-rt, r=m-ou-se 12a12d4f161 Update includes in '/library/core/src/error.rs'; 5a5d80fb80a Fix building `std` for Hermit after `c_char` change bfe81248fa4 Fix `Path::is_absolute` on Hermit 5d2388da58b Reword prelude for AsyncFn stabilization 9731c019cbe Stabilize async closures fd9b9cd330a Fix typos in docs on provenance 7837903093e feat: clarify how to use `black_box()` 0c7c57b9e3c Add unwrap_unsafe_binder and wrap_unsafe_binder macro operators 72e40f07dfe Rollup merge of #134179 - zachs18:align_offset_mut_ptr_doc, r=workingjubilee 67ef22c7127 Rollup merge of #134178 - ehuss:stabilize-2024-prelude, r=amanieu,traviscross,tgross35 0834c1f1db0 Rollup merge of #134155 - sthibaul:unsafe_op_in_unsafe_fn, r=tgross35 09d16d15513 Rollup merge of #133859 - bjorn3:move_tests_to_alloctests, r=tgross35 94ec2233bd0 Rollup merge of #122003 - mati865:gnullvm-build-libunwind, r=petrochenkov fa1541a5660 Stabilize the Rust 2024 prelude 6942ce52e34 Auto merge of #134177 - matthiaskrgr:rollup-hgp8q60, r=matthiaskrgr 3a1745b09e5 Rollup merge of #133598 - ChayimFriedman2:get-many-mut-detailed-err, r=scottmcm 566ea0f3dd8 Rollup merge of #132975 - arichardson:ffi-c-char, r=tgross35 ed224f8c25a Remove consteval note from <*mut T>::align_offset docs. 197f4744559 Rollup merge of #134079 - tbu-:pr_doc_x8_to_from_xe_bytes, r=jhpratt ff50c42ded8 Add a note saying that `{u8,i8}::from_{be,le,ne}_bytes` is meaningless 809dc2d9649 Forbid unsafe_op_in_unsafe_fn in hurd-specific os and sys files 420c83c0cd8 Rollup merge of #134116 - RalfJung:const_nonnull_new, r=jhpratt bb71e111888 Rollup merge of #134100 - eholk:noop-rustc-const-stable, r=dtolnay d846ee80d9e Add references to the specific ABI documents faa946af9e7 Remove l4re from the unsigned char operating system list c589942e7af De-duplicate and improve definition of core::ffi::c_char f5dfac33df4 stabilize const_nonnull_new e24f63040e1 Rollup merge of #133472 - rust-wasi-web:master, r=joboet 0c9c5edf2d9 Rollup merge of #133456 - clubby789:cargo-update, r=ChrisDenton 1079f47e289 Rollup merge of #133184 - osiewicz:wasm-fix-infinite-loop-in-remove-dir-all, r=Noratrieb 577c96562be Remove rustc_const_stable attribute on const NOOP 7234c4f09e7 Rollup merge of #134032 - snprajwal:fix-docs, r=joboet 24e395ad1ab core: use public method instead of instrinsic 3a36268f22b core: improve comments a09c0403f2d Auto merge of #134052 - matthiaskrgr:rollup-puxwqrk, r=matthiaskrgr a9c38ee0d29 Rollup merge of #134050 - RalfJung:miri-sync, r=RalfJung 6fa0126c89c Rollup merge of #133880 - ChrisDenton:homedir, r=Mark-Simulacrum 0e491a9a3b1 Rollup merge of #133789 - rossmacarthur:then-with-doc-alias, r=Mark-Simulacrum ed50cd40ea2 Switch inline(always) in core/src/fmt/rt.rs to plain inline 886328011ef Downgrade cc e9bfb10f867 Rollup merge of #134013 - BLANKatGITHUB:intrinsic, r=saethlin 4e0eec33e6f Adds new intrinsic declaration c1d57f82a0e Rollup merge of #133987 - Will-Low:DefineTlsAcronym, r=workingjubilee 8f4016eba75 docs: better examples for `std::ops::ControlFlow` a73f6c64a01 Merge from rustc fd6e8d7358e Auto merge of #133978 - matthiaskrgr:rollup-6gh1iho, r=matthiaskrgr 069b38123a6 Merge from rustc 5852362e5d1 Define acronym for thread local storage 70e63e17b2c Auto merge of #118159 - EliasHolzmann:formatting_options, r=m-ou-se 3bcad5cb18b Rollup merge of #132187 - shahn:extend_more_tuples, r=dtolnay f761e9c676f Rollup merge of #130254 - GrigorenkoPV:QuotaExceeded, r=dtolnay ef4c4ae6b50 Rollup merge of #130209 - GrigorenkoPV:CrossesDevices, r=dtolnay 11e4cd165ae Auto merge of #133089 - eholk:stabilize-noop-waker, r=dtolnay aa5fc647d04 core: implement `bool::select_unpredictable` 70153836edd Rollup merge of #133790 - HypheX:improve-vec-docs, r=harudagondi,workingjubilee ca5965a8639 Merge from rustc 706da00d0ff Rollup merge of #133821 - Kobzol:replace-black-with-ruff, r=onur-ozkan debbad652d9 Stabilize noop_waker fa414d5787d Access members of `FormattingOptions` directly instead of via getters/setters 02156e9faf6 Removed constness for methods receiving a `&mut` parameter a0526432656 Added better reason for exposing `flags` and `get_flags` as unstable 9492becae41 Formatted 322c8b766b2 Refactored FormattingOptions to use a bitmask for storing flags a1b4810cfcf Revert "Turned public+unstable+hidden functions into private functions" 8bd8c11c06a Turned public+unstable+hidden functions into private functions 177d5fac526 Made all fns const b06f16ba681 impl Default for fmt::FormattingOptions 157c4f662e0 Fixed copy+paste error in comment 8fe085f1349 fmt::FormattingOptions: Renamed `alignment` to `align` 7de3770f6c6 Formatter::with_options: Use different lifetimes 3d16495ff6c Fixed another broken test 4d3d0470d23 Added struct `fmt::FormattingOptions` 29f1b2498b6 Formatter: Access members via getter methods wherever possible 7f0a865ead6 Improve documentation 4155a213e3e Add libc funcitons only for wasm32-wasip1-threads. a58d30811b5 Fix compilation for wasm32-wasip1 (without threads). 2834b3e1213 Rollup merge of #133882 - jyn514:doc-backtraces, r=saethlin 37f75ad5a08 Rollup merge of #133844 - RalfJung:simd_relaxed_fma-nondet, r=workingjubilee b89e20d1e5e Rollup merge of #127565 - esp-rs:xtensa-vaargs, r=workingjubilee 7af25276b17 Rollup merge of #133863 - oli-obk:push-pystoxvtvssx, r=lqd f4ab4b484fe Rollup merge of #118833 - Urgau:lint_function_pointer_comparisons, r=cjgillot db3e689077b Improve comments for the default backtrace printer 8874ede0208 Expand home_dir docs 33345baf830 Reformat Python code with `ruff` 6cfe2423972 Rename `core_pattern_type` and `core_pattern_types` lib feature gates to `pattern_type_macro` 8d19d7cf046 Move some alloc tests to the alloctests crate b75783a7146 clarify simd_relaxed_fma non-determinism 04abf699af3 Rollup merge of #133651 - scottmcm:nonnull-nonzero-no-field-projection, r=oli-obk 59c58640a80 Auto merge of #133818 - matthiaskrgr:rollup-iav1wq7, r=matthiaskrgr 6bebe1c8423 Rollup merge of #133726 - joshtriplett:breakpoint, r=oli-obk 57dbb716624 Rollup merge of #132937 - xmh0511:master, r=m-ou-se 1a1fa731d58 Update `NonZero` and `NonNull` to not field-project (per MCP807) 8df6841cf41 Rollup merge of #133796 - TDecking:borrowing-sub, r=tgross35 5248edd2723 Rollup merge of #133762 - RalfJung:const-size-of-val, r=workingjubilee 97f98da1fce Rollup merge of #133696 - RalfJung:const-hashmap, r=cuviper 592d87fafca Use UNIX thread_local implementation for WASI. 0b39639fa39 Update the definition of `borrowing_sub` 2f0494f936b Teach rust core about Xtensa VaListImpl and add a custom lowering of vaarg for xtensa. fb668a45993 Add `core::arch::breakpoint` and test 1ae06991054 Add doc alias 'then_with' for `then` method on `bool` 04e41db91f5 ./x miri: fix sysroot build a351bae8511 Rollup merge of #133395 - calebzulawski:simd_relaxed_fma, r=workingjubilee 6dd07606b78 Rollup merge of #133763 - Urgau:f16-midpoint-const-feat, r=Amanieu 7ef9e82c0ea Rollup merge of #133701 - kornelski:c-str, r=workingjubilee e5e10c242ac Rollup merge of #131713 - tgross35:stabilize-const_maybe_uninit_write, r=RalfJung,dtolnay eb96f323fa0 stabilize const_{size,align}_of_val 2b42df79e1a Stabilize `const_maybe_uninit_write` 7b043597c80 Use c"lit" for CStrings without unwrap b06cd98bd77 Allow fn pointers comparisons lint in library 3d21446fa49 Fix `f16::midpoint` const feature gate 072ea73a1f6 Rollup merge of #133743 - bjoernager:slice-as-array, r=joboet 21529533fde stabilize const_collections_with_hasher and build_hasher_default_const_new 166cfb13136 Auto merge of #133728 - jhpratt:rollup-k1i60pg, r=jhpratt ec43e851a59 Fix docs for '<[T]>::as_array'; 4a95157e48e Rollup merge of #133678 - Urgau:stabilize-ptr_fn_addr_eq, r=jhpratt f7d558398a2 Rollup merge of #133672 - RalfJung:const-stability-cleanup, r=jhpratt cf34b1540ea Rollup merge of #133711 - cod10129:master, r=Noratrieb 45418e9d2a6 Rollup merge of #131784 - Urgau:stabilize-midpoint, r=dtolnay 0ba4fb63cc1 Rollup merge of #131416 - okaneco:const_copy, r=RalfJung 58b87f49645 Mark `slice::copy_from_slice` unstably const 50363a21191 add isatty alias for is_terminal 06c9316079c Rollup merge of #133674 - scottmcm:chain-carrying-add, r=Amanieu b2f5848193a Rollup merge of #133669 - RalfJung:const_swap_splitup, r=dtolnay 833dd81deba Run `cargo update` and update licenses 5c2d5ca1784 Stabilize unsigned `num_midpoint` feature f4630c8d109 Rollup merge of #133686 - samueltardieu:push-xkxwxzxqokuu, r=compiler-errors 487eef7a511 Rollup merge of #133622 - mkroening:exception-blog, r=cuviper 84b80170276 Rollup merge of #133602 - SanchithHegde:fix-pathbuf-example-codeblocks, r=cuviper 2bfc089b74f Rollup merge of #133515 - SteveLauC:fix/hurd, r=ChrisDenton 964c0c061fe Rollup merge of #128184 - joboet:refactor_pthread_sync, r=workingjubilee 7b3ae4b14e8 Auto merge of #133684 - RalfJung:rollup-j2tmrg7, r=RalfJung b7abc7692ff Switch rtems target to panic unwind afea5597238 Add diagnostic item for `std::ops::ControlFlow` d17c5979b26 Rollup merge of #133670 - RalfJung:hashbrown, r=Amanieu 6965d9c1b06 Auto merge of #133659 - jieyouxu:rollup-576gh4p, r=jieyouxu e142fe090ef std: clarify comments about initialization 0236bd2058d Stabilize `ptr::fn_addr_eq` a54b5c85a48 Add value accessor methods to `Mutex` and `RwLock` ec760c9108f fix: hurd build, stat64.st_fsid was renamed to st_dev 550bfc05b24 rustc_allow_const_fn_unstable is not used in proc_macro 1ccf19dc122 get rid of a bunch of unnecessary rustc_const_unstable 70183029716 Fix chaining `carrying_add`s dd29fadf097 add test for bytewise ptr::swap of a pointer a7f3a3cc076 remove a whole bunch of unnecessary const feature gates 943aa44906f Abstract `ProcThreadAttributeList` into its own struct e6a732b0db2 move swap_nonoverlapping constness to separate feature gate 9d56b9dbedd bump hashbrown version e423a339a39 move slice::swap_unchecked constness to slice_swap_unchecked feature gate 46851ab5cc9 Rollup merge of #133548 - cuviper:btreeset-entry-api, r=Mark-Simulacrum b6bb042b28c Rollup merge of #133496 - rust-wasi-web:wasi-available-parallelism, r=Amanieu 5e218fe390d Rollup merge of #133106 - BLANKatGITHUB:intrinsic, r=RalfJung 3b2bca7e9f0 Rollup merge of #132515 - kornelski:home_fix, r=jhpratt 407d5985ad5 Rollup merge of #133625 - RalfJung:custom-mir-debug-info, r=compiler-errors a0b4e2ff644 Rollup merge of #116161 - Soveu:varargs2, r=cjgillot eeb808edfce Auto merge of #133533 - BoxyUwU:bump-boostrap, r=jieyouxu,Mark-Simulacrum 2992ba7e050 refine mir debuginfo docs bf4636bee39 Doc comment custom MIR debuginfo. 547854bab55 update link to "C++ Exceptions under the hood" blog c145db8fec3 Rollup merge of #133530 - timvisee:master, r=jhpratt 3ccd6102eae Rollup merge of #133466 - aksh1618:patch-1, r=thomcc e5e4ec16636 fix: fix codeblocks in `PathBuf` example 069a3f311a4 Auto merge of #123244 - Mark-Simulacrum:share-inline-never-generics, r=saethlin aa2609a583f Change `GetManyMutError` to match T-libs-api decision e97ec53b763 Share inline(never) generics across crates 68d3ed3d908 Also use zero when referencing to capacity or length 657e081ba8f Use consistent wording in docs, use zero instead of 0 e97f024d14b Auto merge of #133561 - GuillaumeGomez:rollup-g4upmv4, r=GuillaumeGomez c8ce91a5e34 Rollup merge of #133543 - mustartt:aix-lgammaf_r-shim, r=cuviper 3d06a7c117e Rollup merge of #133512 - bjoernager:slice-as-array, r=Amanieu 5a2e12351d7 Rollup merge of #129409 - grinapo:patch-1, r=Amanieu 64d66ce14ba Rollup merge of #133498 - GuillaumeGomez:missing-examples, r=joboet 95afca906a6 Stabilize `extended_varargs_abi_support` 8416a6beeca Fill in a `BTreeSet::entry` example 32276df18d5 Add a tracking issue for `btree_set_entry` 0b8b46754ae Add `BTreeSet` entry APIs to match `HashSet` de67dab738c fmt b255bcd4709 update cfgs d5ee74c8b2c Implement code review cc94a61244f replace placeholder version ea762e31d64 Auto merge of #133369 - Zalathar:profiler-builtins-no-core, r=jieyouxu be4d7f97a51 Rollup merge of #133449 - joboet:io_const_error, r=tgross35 fddc6136036 Rollup merge of #133402 - compiler-errors:drop-and-destruct, r=lcnr b5baaaa3d2a Auto merge of #133505 - compiler-errors:rollup-xjp8hdi, r=compiler-errors 11a4630ce28 chore: Improve doc comments d3ade682724 Add '<[T]>::as_array', '<[T]>::as_mut_array', '<*const [T]>::as_array', and '<*mut [T]>::as_mut_array' conversion methods; cdf278252ad std: update internal uses of `io::const_error!` 182e0fde338 Rollup merge of #133435 - RalfJung:test_downgrade_observe, r=tgross35 6e22739b070 Rollup merge of #133282 - tgross35:maybe-uninit-debug, r=Amanieu 585dfc5b52e Rollup merge of #133136 - ChayimFriedman2:get-many-mut, r=Amanieu 75101ecc49d Rollup merge of #133042 - cuviper:btreemap-insert_entry, r=Amanieu c590ef03caa Rollup merge of #133464 - RalfJung:whitespace-panic, r=joboet b0910ed9eec Rollup merge of #133419 - CromFr:add-path-strip_prefix-test-example, r=Amanieu ec61c1e49a2 Add missing code examples on `LocalKey` c8c96e00fdc thread::available_parallelism for wasm32-wasip1-threads 85ceea5ea32 Refactor ReadDir into a state machine 9e9b5eeb86b Run TLS destructors for wasm32-wasip1-threads 2dec6432dc5 Fix typos in pin.rs 02b3316cbb9 std::thread: avoid leading whitespace in some panic messages ee91620dbef Constify Drop and Destruct 7abb3262e5d std: expose `const_io_error!` as `const_error!` 786c3e18dcb Auto merge of #133247 - GuillaumeGomez:reduce-integer-display-impl, r=workingjubilee 992b1d2573c Support ranges in `<[T]>::get_many_mut()` 41bd055eaed miri: disable test_downgrade_observe test on macOS ca2246ba724 Rollup merge of #132982 - suaviloquence:2-doc-changed-alloc-methods, r=Mark-Simulacrum 6e2012f32d9 Rollup merge of #132533 - SUPERCILEX:patch-4, r=Mark-Simulacrum ed2598bafce fix `Allocator` method names in `alloc` free function docs fd68d3e37ee Rollup merge of #133298 - n0toose:remove-dir-all-but-not-paths, r=Noratrieb 74f078b7290 Rollup merge of #133260 - compiler-errors:deref, r=fee1-dead d1cf863b68f Rollup merge of #132730 - joboet:after_main_sync, r=Noratrieb 3f9124b0cf3 Added a doc test for std::path::strip_prefix cea713a6711 Rollup merge of #133389 - eduardosm:stabilize-const_float_methods, r=RalfJung 04dab39dbea Rollup merge of #133301 - GuillaumeGomez:add-example-wrapping-neg, r=workingjubilee dd7b253bb5d changes old intrinsic declaration to new declaration ce181b51151 Auto merge of #132611 - compiler-errors:async-prelude, r=ibraheemdev 9fc2c20cb23 Auto merge of #132597 - lukas-code:btree-plug-leak, r=jhpratt 7f63ef45955 Make profiler_builtins `#![no_core]` instead of just `#![no_std]` 75fe14cbea0 Remove unnecessary `#![allow(unused_features)]` 8ff9319664c Sort and separate lint/feature attributes in `profiler_builtins` 000c27de7b8 Constify Deref and DerefMut e105ad36675 Match simd_relaxed_fma documentation to fmuladd intrinsic bc1b909d1cf Auto merge of #133379 - jieyouxu:rollup-00jxo71, r=jieyouxu a0222ed6f11 Add simd_relaxed_fma intrinsic 18a772c0abf Stabilize `const_float_methods` 1fa5b7136ba Auto merge of #133377 - jieyouxu:rollup-n536hzq, r=jieyouxu 5048c462f73 Improve code by using `unsigned_abs` e8829bde64b Rollup merge of #133237 - fee1-dead-contrib:constadd, r=compiler-errors 4151e360996 Rollup merge of #133332 - bjoernager:const-array-as-mut-slice, r=jhpratt 842ed39a839 Rollup merge of #131505 - madsmtm:darwin_user_temp_dir, r=dtolnay 0b0403aade1 Auto merge of #132994 - clubby789:cc-bisect, r=Kobzol 44de774c840 Auto merge of #133360 - compiler-errors:rollup-a2o38tq, r=compiler-errors 6ea276ef35c Rollup merge of #133264 - lolbinarycat:os-string-truncate, r=joboet 5a6926c6a54 Auto merge of #132329 - compiler-errors:fn-and-destruct, r=lcnr 8cace9e9e4d Shorten the `MaybeUninit` `Debug` implementation 9fff2a79a89 aix: create shim for lgammaf_r 0c2dadaf889 Add code example for `wrapping_neg` method for signed integers b0893a5fb1d Deduplicate checking drop terminator 25cfe493429 Gate const drop behind const_destruct feature, and fix const_precise_live_drops post-drop-elaboration check df5f774cf44 Auto merge of #133339 - jieyouxu:rollup-gav0nvr, r=jieyouxu fd9dfbfa58e Rollup merge of #133337 - ColinFinck:thread-scoped-fix-typo, r=joboet 6ca197967f0 Rollup merge of #133330 - RalfJung:close, r=the8472 8cec9604aec Rollup merge of #133313 - thesummer:fix-arc4random, r=cuviper bd8c70b7603 Rollup merge of #133288 - bjoernager:const-array-each-ref, r=jhpratt c9a80ad59f4 Rollup merge of #133238 - heiher:loong-stdarch-rexport, r=Amanieu 0eb96d1dc9c Auto merge of #130867 - michirakara:steps_between, r=dtolnay c57bc831f1c Fix typo in `std::thread::Scope::spawn` documentation. b621e5886f5 Mark '<[T; N]>::as_mut_slice' as 'const'; 01df57db50c library: update comment around close() 125a43354b7 Don't try to use confstr in Miri dc9cd998086 Auto merge of #129238 - umgefahren:stabilize-ipv6-unique-local, r=dtolnay e515d5fdd20 distinguish overflow and unimplemented in Step::steps_between 7e9c665fcec Use arc4random of libc for RTEMS target fb92c4e9f3f Mention that std::fs::remove_dir_all fails on files 7edd22c19b6 Mark and implement 'each_ref' and 'each_mut' in '[T; N]' as const; e411c3361f6 constify `Add` 956d316aa96 Rollup merge of #131736 - hoodmane:emscripten-wasm-bigint, r=workingjubilee 8defa07da76 implement OsString::truncate 9dd9ebdafe5 Rollup merge of #133226 - compiler-errors:opt-in-pointer-like, r=lcnr c3a7a9ea54d Rollup merge of #130800 - bjoernager:const-mut-cursor, r=joshtriplett 05d96c22b33 Rollup merge of #129838 - Ayush1325:uefi-process-args, r=joboet 7691bc11882 Make PointerLike opt-in as a trait 5c581c3aadf Reduce integer `Display` implementation size c819ed39def Stabilize const_pin_2 bb443655059 re-export `is_loongarch_feature_detected` 63a5059a757 Rollup merge of #132732 - gavincrawford:as_ptr_attribute, r=Urgau f48d6a9b1d9 UniqueRc: platform-specific AsFd/Handle/etc impls to mirror Rc e3055f65ed6 UniqueRc: PinCoerceUnsized and DerefPure f53e523d3c8 UniqueRc: comparisons and Hash 5f8f1a32611 Rollup merge of #133183 - n0toose:improve-remove-dir-docs, r=joboet 88965979fa9 Rollup merge of #125405 - m-ou-se:thread-add-spawn-hook, r=WaffleLapkin 4da0cb33032 Rollup merge of #123947 - zopsicle:vec_deque-Iter-as_slices, r=Amanieu 31096758b3f UniqueRc: Add more trait impls. 4f1707779d3 Update doc comments for spawn hook. e7cb7389192 Address review comments. 595f0d9f0f8 Fix tracking issue. 4fe82dfc2b3 Add tracking issue. 56ea82557bd Use Send + Sync for spawn hooks. 977c4c304f2 Add thread Builder::no_hooks(). e253c673db1 Update thread spawn hooks. 053640f6f35 Use add_spawn_hook for libtest's output capturing. 2a846d803f4 Add std::thread::add_spawn_hook. 525dab97bb6 Correct comments concerning updated dangling pointer lint d2430399b75 Auto merge of #133205 - matthiaskrgr:rollup-xhhhp5u, r=matthiaskrgr 3c67ef9e5a2 Rollup merge of #133200 - RalfJung:miri-rwlock-test, r=tgross35 3516801bae2 ignore an occasionally-failing test in Miri 207627c1104 Rollup merge of #133182 - RalfJung:const-panic-inline, r=tgross35 fb525301a5f Rollup merge of #132758 - nnethercote:improve-get_key_value-docs, r=cuviper 3bd5a7f4276 Mention std::fs::remove_dir_all in std::fs::remove_dir 40ecf6c22bf wasi/fs: Improve stopping condition for ::next 6da3fda3593 Bump `stdarch` to the latest master d70eaaa68ec const_panic: inline in bootstrap builds to avoid f16/f128 crashes 1da1cc9cf07 std: allow after-main use of synchronization primitives 307d6f22226 Auto merge of #133160 - jhpratt:rollup-wzj9q15, r=jhpratt e09425b475c Rollup merge of #133145 - kornelski:static-mutex, r=traviscross 58da10b98d8 Auto merge of #128219 - connortsui20:rwlock-downgrade, r=tgross35 997906157b4 rename rustc_const_stable_intrinsic -> rustc_intrinsic_const_stable_indirect 601132a1007 Improve `{BTreeMap,HashMap}::get_key_value` docs. 2e135b01a22 Document alternatives to `static mut` bde38e315d0 Auto merge of #120370 - x17jiri:likely_unlikely_fix, r=saethlin b407a672d3c Likely unlikely fix f1532b9b5b2 Rollup merge of #133126 - ohno418:fix-String-doc, r=jhpratt 91ab1736cfe Rollup merge of #133116 - RalfJung:const-null-ptr, r=dtolnay 6f53685158e alloc: fix `String`'s doc 61efdcc7741 clean up const stability around UB checks c313f7e9291 stabilize const_ptr_is_null 6aced621042 Rollup merge of #132449 - RalfJung:is_val_statically_known, r=compiler-errors 0250296af6c Rollup merge of #131717 - tgross35:stabilize-const_atomic_from_ptr, r=RalfJung d27c37b4c4a reduce threads in downgrade test 8619ddabd64 fix `DOWNGRADED` bit unpreserved 45a5a4e3f1d fix memory ordering bug + bad test 525248ca5db add safety comments for queue implementation e2543ddca9c add `downgrade` to `queue` implementation c05bcc9c7fb modify queue implementation documentation ddd48e97263 add `downgrade` to `futex` implementation f9bcdb4474d add simple `downgrade` implementations 54967218559 add `downgrade` method onto `RwLockWriteGuard` dcda8df4676 add `RwLock` `downgrade` tests 49b742da57d Rollup merge of #133050 - tgross35:inline-f16-f128, r=saethlin 9b405001aa8 Rollup merge of #133048 - cyrgani:ptr-doc-update, r=Amanieu 3357615fc72 Rollup merge of #133019 - sorairolake:add-missing-period-and-colon, r=tgross35 7e17a11e61d Rollup merge of #132984 - sunshowers:pipe2, r=tgross35 e8a67ba743b Rollup merge of #132977 - cberner:fix_solaris, r=tgross35 dbd5fb14b17 Rollup merge of #132790 - aDotInTheVoid:ioslice-asslice-rides-again, r=cuviper 1b4ad7703eb Pass `f16` and `f128` by value in `const_assert!` e4c94766246 Remove one stray space. 58c02681d8f use `&raw` in `{read, write}_unaligned` documentation 1239f03791f btree: add `{Entry,VacantEntry}::insert_entry` 9aa607df7aa Auto merge of #132709 - programmerjake:optimize-charto_digit, r=joshtriplett 78626b047b6 Rollup merge of #133027 - no1wudi:master, r=jhpratt c6347be9b59 Auto merge of #133026 - workingjubilee:rollup-q8ig6ah, r=workingjubilee 28f9f7f6736 Fix a copy-paste issue in the NuttX raw type definition c1bd3483194 Rollup merge of #133008 - onur-ozkan:update-outdated-comment, r=jieyouxu 51884ccd46d Rollup merge of #133004 - cuviper:unrecover-btree, r=ibraheemdev 9d1b5289926 Rollup merge of #133003 - zachs18:clonetouninit-dyn-compat-u8, r=dtolnay 275fab34cf3 Rollup merge of #132907 - BLANKatGITHUB:intrinsic, r=saethlin 265f69fd7de Rollup merge of #131304 - RalfJung:float-core, r=tgross35 521d06b1f3a Auto merge of #122770 - iximeow:ixi/int-formatting-optimization, r=workingjubilee 0874a0035d0 docs: Fix missing colon in methods for primitive types 524cbdaf3b7 docs: Fix missing period in methods for integer types 948e53de4bb Auto merge of #133006 - matthiaskrgr:rollup-dz6oiq5, r=matthiaskrgr 4a5f8c13225 update outdated comment about test-float-parse 5b9d092b2cf Rollup merge of #126046 - davidzeng0:mixed_integer_ops_unsigned_sub, r=Amanieu 0ec0a66f5ca Auto merge of #132662 - RalfJung:const-panic-inlining, r=tgross35 3a28e6e022a Update core CloneToUninit tests 35e1775fe1f btree: simplify the backdoor between set and map 0495cd155b6 Bump `cc` ec80ac9760a Fix compilation error on Solaris due to flock usage cdcb1d2d589 Auto merge of #132556 - clubby789:cargo-update, r=Mark-Simulacrum a66f410edcd Run `cargo update` and update licenses 1cccc6a94cc const_panic: don't wrap it in a separate function f79ecc84837 [illumos] use pipe2 to create anonymous pipes 46925ba44db Auto merge of #132883 - LaihoE:vectorized_is_sorted, r=thomcc 4ccf16b1eb0 Auto merge of #132972 - matthiaskrgr:rollup-456osr7, r=matthiaskrgr fe508063c28 Rollup merge of #132970 - tyilo:nonzero-u-div-ceil-issue, r=tgross35 e35eeacfc3e Rollup merge of #132966 - RalfJung:const_option_ext, r=jhpratt d1b467ef3b0 Rollup merge of #132948 - RalfJung:const_unicode_case_lookup, r=Noratrieb 5a207560656 Rollup merge of #132851 - chansuke:update-comment, r=thomcc ff8020378de Auto merge of #132870 - Noratrieb:inline-int-parsing, r=tgross35 7f43800757b Add tracking issue number to unsigned_nonzero_div_ceil feature dfdaf4d0da8 Make `CloneToUninit` dyn-compatible a6ab20eb090 stabilize const_option_ext aef6c7529bf Rollup merge of #132541 - RalfJung:const-stable-extern-crate, r=compiler-errors 9792fc3fa32 stabilize const_unicode_case_lookup 7cd4be6ea3f Stabilize `Ipv6Addr::is_unique_local` and `Ipv6Addr::is_unicast_link_local` 15b4af14a52 adds new declaration to codegen 513cbf8297b Auto merge of #132943 - matthiaskrgr:rollup-164l3ej, r=matthiaskrgr a636ccb7e8c Rollup merge of #132914 - rcorre:cell-grammar, r=tgross35 5af9cd39bdb Rollup merge of #132895 - scottmcm:generalize-nonnull-from-raw-parts, r=ibraheemdev bd35c207e83 remove no-longer-needed abs_private 71c0928f8e5 allow rustc_private feature in force-unstable-if-unmarked crates 2d1521ec8d3 Rollup merge of #132929 - cuviper:check-alloc_zeroed, r=tgross35 ba37edb8236 Rollup merge of #132869 - lolbinarycat:library-fix-too_long_first_doc_paragraph, r=tgross35 c3aa0fd6d20 Rollup merge of #132847 - RalfJung:addr-dont-expose, r=Mark-Simulacrum 7b678a96b68 Auto merge of #132919 - matthiaskrgr:rollup-ogghyvp, r=matthiaskrgr fe2df9994be a release operation synchronizes with an acquire operation 59ea28527ec Check for null in the `alloc_zeroed` example 422c4e8dc6b new intrinsic declaration be313a69b63 new intrinsic declaration bf896164821 Rollup merge of #132144 - adetaylor:receiver-trait-itself, r=wesleywiser 95128df8753 Rollup merge of #120077 - SUPERCILEX:set-entry, r=Amanieu 5b2d93dadf0 Update dangling pointer tests ed8add25d55 Tag relevant functions with #[rustc_as_ptr] attribute eee61579d6d Auto merge of #132902 - matthiaskrgr:rollup-43qgg3t, r=matthiaskrgr 6bc254b09ed Update grammar in std::cell docs. bae8842bd22 Emscripten: link with -sWASM_BIGINT 6bc8a98cbb4 Rollup merge of #130999 - cberner:flock_pr, r=joboet 2e3a4db79e1 Auto merge of #127589 - notriddle:notriddle/search-sem-3, r=GuillaumeGomez 08e1228e615 Generalize `NonNull::from_raw_parts` per ACP362 f9a5ed02f86 vectorize slice::is_sorted 318b54e4aa4 `#[inline]` integer parsing functions 2b0fd040446 split up the first paragraph of doc comments for better summaries 863ba5a66b4 Update the doc comment of `ASCII_CASE_MASK` 192601ab1ba elem_offset / subslice_range: use addr() instead of 'as usize' 458dbbd00c3 Rollup merge of #132136 - RalfJung:target-feature-abi-compat, r=Mark-Simulacrum 29571c684a7 honor rustc_const_stable_indirect in non-staged_api crate with -Zforce-unstable-if-unmarked f1e6a403adc Improve documentation of `element_offset` and related methods 6a9d2a411f5 Rename `elem_offset` to `element_offset` 310a91d1a6a Add as_slice/into_slice for IoSlice/IoSliceMut. 450aa1288bd Rollup merge of #132778 - lolbinarycat:io-Error-into_inner-docs, r=cuviper e53a11a5e8f update io::Error::into_inner to acknowlage io::Error::other 3a3ed52ed1d Address review comments 70d11b2f164 Update library/std/src/sys/pal/windows/fs.rs 87dd8ff600f Auto merge of #132717 - RalfJung:rustc_safe_intrinsic, r=compiler-errors d51ad86fa5a remove support for rustc_safe_intrinsic attribute; use rustc_intrinsic functions instead 362e652f6c6 Rollup merge of #132738 - cuviper:channel-heap-init, r=ibraheemdev ca7caf9db4c mark is_val_statically_known intrinsic as stably const-callable 36fd72193f9 Rollup merge of #132696 - fortanix:raoul/rte-235-fix_fmodl_missing_symbol_issue, r=tgross35 256a7ced72c Rollup merge of #132639 - RalfJung:intrinsics, r=workingjubilee,Amanieu 79569ee933c Initialize channel `Block`s directly on the heap db2b12c9066 core: move intrinsics.rs into intrinsics folder 0fa9a6c6c9e Auto merge of #132714 - mati865:update-memchr, r=tgross35 6d60a72a8d9 Rollup merge of #132715 - tabokie:fix-lazy-lock-doc, r=Noratrieb 17e5d3b5522 Rollup merge of #132665 - tyilo:nonzero-u-div-ceil, r=joboet da1331d6c40 Separate f128 `%` operation to deal with missing `fmodl` symbol 57cef21786e Auto merge of #132705 - kornelski:inline-repeat, r=tgross35 7802368a477 fix lazylock comment a5d839dc87d Auto merge of #131888 - ChrisDenton:deopt, r=ibraheemdev 64f77df1882 unpin and update memchr 2d7984a960f optimize char::to_digit and assert radix is at least 2 7317cd4555d Inline str::repeat 8446e1a5f47 Rollup merge of #132617 - uellenberg:fix-rendered-doc, r=cuviper df1594bbcf8 Auto merge of #131721 - okaneco:const_eq_ignore_ascii_case, r=m-ou-se 7e7f9ed6a32 Add `is_ascii` function optimized for x86-64 for [u8] b76ab440a07 Auto merge of #132500 - RalfJung:char-is-whitespace-const, r=jhpratt a442ac02b25 Add new implementation benchmark 5c39de3744c Add new unstable feature `const_eq_ignore_ascii_case` 3adbc621669 Auto merge of #132664 - matthiaskrgr:rollup-i27nr7i, r=matthiaskrgr 8ddab887db1 Change some code blocks to quotes in rendered std doc ef47b33a8cb Rollup merge of #131261 - clarfonthey:unsafe-cell-from-mut, r=m-ou-se dc052ced3b7 Auto merge of #132661 - matthiaskrgr:rollup-npytbl6, r=matthiaskrgr 9be5c2dc1de Implement div_ceil for NonZero b39a2860435 Rollup merge of #132571 - RalfJung:const_eval_select_macro, r=oli-obk 3a28e6ad6b1 Rollup merge of #132473 - ZhekaS:core_fmt_radix_no_panic, r=joboet 46c3034cd24 Rollup merge of #132153 - bjoernager:const-char-encode-utf16, r=dtolnay d52956082bc add const_eval_select macro to reduce redundancy 9250b4c4b59 Rollup merge of #132609 - NotWearingPants:patch-1, r=Amanieu 54bd3adf0e3 Rollup merge of #132606 - eduardosm:char-slice-str-pattern-doc, r=tgross35 6b9a5af164d most const intrinsics don't need an explicit rustc_const_unstable any more 49143b3b622 add new rustc_const_stable_intrinsic attribute for const-stable intrinsics 031f9c28368 convert all const-callable intrinsics into the new form (without extern block) 127883633f8 docs: fix grammar in doc comment at unix/process.rs ff59429bddf Improve example of `impl Pattern for &[char]` a68e38323fc Add AsyncFn* to to the prelude in all editions b8fe4fde115 Fixed typo, rebased 29a8fc997da Updated SAFETY comment to address underflow 008a74c9f20 Replace checked slice indexing by unchecked to support panic-free code ceac65d1adf Rollup merge of #132579 - RalfJung:rustc-std-workspace-crates, r=Amanieu 2ccb95e8380 btree: don't leak value if destructor of key panics 27c96552095 Stabilise 'const_char_encode_utf16'; 509dd073b69 Auto merge of #132586 - workingjubilee:rollup-qrmn49a, r=workingjubilee 4926ac05cdf update rustc-std-workspace crates 8d4546d424f Rollup merge of #132423 - RalfJung:const-eval-align-offset, r=dtolnay ae28b877064 Auto merge of #132434 - tgross35:f128-tests, r=workingjubilee b82b6a45cf7 Fix and undeprecate home_dir() db581d1e2bf Enable `f128` tests on all non-buggy platforms 🎉 9e03f8084c3 Auto merge of #132581 - workingjubilee:rollup-4wj318p, r=workingjubilee c506c0279ef Update `compiler_builtins` to 0.1.138 and pin it 4a3b0948bbe Rollup merge of #132563 - frectonz:master, r=Amanieu 803847138ff Auto merge of #123723 - madsmtm:apple-std-os, r=dtolnay f2175096363 Auto merge of #132479 - compiler-errors:fx-feat-yeet, r=fee1-dead caacc66a634 Rename the FIXMEs, remove a few that dont matter anymore 8bb7ce8a697 Auto merge of #132542 - RalfJung:const_panic, r=tgross35 72beb748321 remove const-support for align_offset 48f72455d35 Modify `NonZero` documentation to reference the underlying integer type b10bc73da0a Rollup merge of #132511 - RalfJung:const_arguments_as_str, r=dtolnay dee386e7977 Rollup merge of #132503 - RalfJung:const-hash-map, r=Amanieu 028616a5bca Rollup merge of #132499 - RalfJung:unicode_data.rs, r=tgross35 a04ae3433a7 Rollup merge of #132393 - zedddie16:issue-131865-fix, r=tgross35 99edf316755 Rollup merge of #131377 - rick-de-water:nonzero-exp, r=dtolnay 141ffe504bd Rollup merge of #129329 - eduardosm:rc-from-mut-slice, r=dtolnay 0f4c0ab62ba add const_panic macro to make it easier to fall back to non-formatting panic in const 0bad6557b73 stabilize const_arguments_as_str c77491eb408 Auto merge of #132458 - RalfJung:rustc-const-unstable, r=Amanieu 39157edbc09 Rustdoc: added brief colon explanation e4225758db0 Add Set entry API 578b3ff91b0 Add BorrowedBuf::into_filled{,_mut} methods to allow returning buffer with original lifetime 2037eace73d Rollup merge of #132495 - Houtamelo:remove_unintended_link, r=jieyouxu 31a805b08cf Rollup merge of #132493 - Houtamelo:doc_type-ref_html-tag, r=jieyouxu c2f25cd880d Rollup merge of #132482 - lukas-code:stab-attrs, r=Noratrieb cc5191d1d82 remove const_hash feature leftovers 2728af9203a const_with_hasher test: actually construct a usable HashMap a4a50b1b672 make char::is_whitespace unstably const 970eae4d52b unicode_data.rs: show command for generating file f5f55442e3f get rid of a whole bunch of unnecessary rustc_const_unstable attributes b14c6792db7 Rollup merge of #132398 - krtab:add_doc_link, r=Noratrieb 6f094ac1107 Remove unintended link a74274e4c08 Fix type reference in documents which was being confused with html tags. 033cb2e7928 fix some stability annotations bd16467dcc4 Rollup merge of #132459 - RalfJung:byte_sub_ptr, r=scottmcm e145c80b018 Rollup merge of #132455 - RalfJung:const_alloc_layout, r=dtolnay c22c341e06a Rollup merge of #132451 - RalfJung:less-rustc_allow_const_fn_unstable, r=tgross35 3bbba3d8bab Rollup merge of #132445 - RalfJung:const-unchecked-shifts, r=tgross35 7df01bee11b Rollup merge of #132413 - lolbinarycat:offset_of_nested-docs, r=workingjubilee 0579de67e47 remove no-longer-needed attribute b56688f9d64 add missing safety comments d12f27d4ef9 adjust test gating for f16/f128 d80df07dc04 float types: move copysign, abs, signum to libcore 5f86b1888e2 offset_from / sub_ptr docs: emphasize that pointers must be in the same allocation c34766cbcdc feat(byte_sub_ptr): add ptr::byte_sub_ptr 080a2e20906 make const_alloc_layout feature gate only about functions that are already stable e12063485b9 unchecked_shifts, unchecked_neg are safe-to-const-expose-on-stable, so we can get rid of a bunch of attributes 53bc80ca335 remove some unnecessary rustc_allow_const_fn_unstable 9661266001a Auto merge of #132206 - tgross35:update-builtins, r=wesleywiser c5d1f3effc7 use semantic line break 804ea40144f update offset_of! docs to reflect the stablization of nesting 1f1310db6fc Add intra-doc link in str::xxx_char_boundary 93963fe694b Add a `collect_into` tuple test case e19e4426450 Don't impl Extend for 13-tuples 86598670051 rustdoc-search: simplify rules for generics and type params ea2ceffe08d Remove do_not_const_check from Iterator methods f7e46bc4e8d Add intra-doc link in str::xxx_prefix ad90a435921 Auto merge of #132238 - Urgau:midpoint-i64-hackers-impl, r=joboet b1a8ad0421e Implement `From<&mut {slice}>` for `Box/Rc/Arc<{slice}>` de81c2cfd47 Auto merge of #132326 - matthiaskrgr:rollup-ngyw18g, r=matthiaskrgr c52ccba99aa Rollup merge of #132321 - betrusted-io:xous/fix-rustc_const_stable-attribute, r=joboet 8148aa07cca Auto merge of #132231 - lukas-code:rc-plug-leaks, r=tgross35 8c010b9c476 xous: sync: remove `rustc_const_stable` attribute 129f8e8c883 Win: rename: Use offset_of! in struct size calculation 38ae7fe6247 Rollup merge of #132270 - yakiimoninja:fs-truncate-docs, r=Noratrieb 94b192d0f13 Rollup merge of #132233 - WaffleLapkin:box-module-split, r=workingjubilee 16b2c9a2db5 Rollup merge of #131520 - zachs18:const-str-split, r=Noratrieb 5a311c1d378 Auto merge of #132277 - workingjubilee:rollup-5e6q6e4, r=workingjubilee f1a9b205273 Stabilize `const_atomic_from_ptr` 2525108f4c5 Auto merge of #128985 - GrigorenkoPV:instantly-dangling-pointer, r=Urgau 5e9f5b7bb19 Rc destructor: tweak inlining 70e917c03c0 Split `boxed.rs` into a few modules fedcb7c717f Rollup merge of #131441 - SpriteOvO:proc-macro-to-tokens-trait, r=dtolnay f156bce99c2 clarified std::fs truncate doc 1050cdf4056 Auto merge of #132145 - RalfJung:stdarch, r=Amanieu ace4a33dfbb clarified doc for `std::fs::OpenOptions.truncate()` 47fa409434a std: refactor `pthread`-based synchronization b1d5523119b New lint: `dangling_pointers_from_temporaries` 64c9d4f1857 Rollup merge of #131391 - ChaiTRex:isqrt, r=scottmcm,tgross35 53780a64b4c we can now enable the 'const stable fn must be stable' check 1f1a027091f bump stdarch 56e3763facb Auto merge of #132251 - jieyouxu:rollup-mtv9mpd, r=jieyouxu 4d02c63de8e Auto merge of #132200 - Mark-Simulacrum:strengthen-cross-lang, r=RalfJung 17cb40d2ccc Support `char::is_digit` in const contexts 77075c6dbc8 Use Hacker's Delight impl in `i64::midpoint` instead of wide `i128` impl 8ce9b1cfab9 Rc/Arc: don't leak the allocation if drop panics 99da8532715 add test for panicking drop in Box/Rc/Arc b737edbfba5 Auto merge of #131284 - dingxiangfei2009:rename-smart-ptr-to-coerce-referent, r=compiler-errors 01a07cd4871 Auto merge of #132191 - Urgau:midpoint_signed_towards_zero, r=dtolnay c3b9a53453f Add a new trait `proc_macro::ToTokens` 3dd1c135709 Update compiler-builtins to 0.1.136 dc9b4671988 Auto merge of #131715 - tgross35:add-const_sockaddr_setters, r=Amanieu c40fc128e80 Make clearer that guarantees in ABI compatibility are for Rust only 9be44cb8f7b Add test for all midpoint expectations c4cdbf7fbb1 Simplify documentation for Extend impl for tuples c528f49e40c Round negative signed integer towards zero in `iN::midpoint` a60439c0bce Rollup merge of #132019 - daboross:document-partialeq-oncelock, r=Mark-Simulacrum c1f1caa4131 Add Extend impls for tuples of arity 1 through 12 b0fc28c0c8b Auto merge of #131349 - RalfJung:const-stability-checks, r=compiler-errors ac13eae8512 Rollup merge of #132137 - RalfJung:behavior, r=Noratrieb a8f0d49ac66 get rid of the internal unlikely macro 752b4f49c6f Re-do recursive const stability checks 58397bb1fdd Arbitrary self types v2: (unused) Receiver trait 8ebd2382ca1 library: consistently use American spelling for 'behavior' 75eb49968ea ABI compatibility: remove section on target features 31b83431cee Rollup merge of #131457 - kpreid:fnaddr, r=dtolnay 3e063d045dc Auto merge of #132121 - workingjubilee:rollup-yrtn33e, r=workingjubilee 60585ca1420 Rollup merge of #132113 - LaihoE:pattern_as_utf8_default_impl, r=workingjubilee b6a311980d5 Rollup merge of #132101 - youknowone:thread_local-gyneiene, r=tgross35 798bde442ca Rollup merge of #132048 - mustartt:aix-random-impl, r=workingjubilee 6feac64de56 Rollup merge of #131851 - sunshowers:musl-posix, r=workingjubilee f5ccf0690b8 Avoid use imports in thread_local_inner! in statik 2e8a2eb7e08 Auto merge of #132116 - matthiaskrgr:rollup-3a0ia4r, r=matthiaskrgr 2a751f0ecfb Rollup merge of #131790 - nmathewson:doc_socketaddr_representation, r=tgross35 7315f476515 Auto merge of #131985 - compiler-errors:const-pred, r=fee1-dead deebbdb006e provide default impl for as_utf8_pattern 478357c2879 Auto merge of #123550 - GnomedDev:remove-initial-arc, r=Noratrieb 2ed812b6ba9 Document textual format of SocketAddrV{4,6} 2dd5cd15ed1 Remove associated type based effects logic c50af69cc05 [musl] use posix_spawn if a directory change was requested ec9c62c5d8b Rollup merge of #130225 - adetaylor:rename-old-receiver, r=wesleywiser 58baa6b1017 Rollup merge of #132066 - tifv:ptr-docs-typo, r=Amanieu 4eafd5f88bf Rollup merge of #132065 - tifv:dangling-docs, r=Noratrieb a351830dc1e Rollup merge of #132060 - joshtriplett:innermost-outermost, r=jieyouxu 726032a41a5 Rollup merge of #132039 - a1phyr:vecdeque_read_exact, r=Noratrieb 52be5ab2eba Rollup merge of #130991 - LaihoE:vectorized_slice_contains, r=Noratrieb ed7dcef9363 const fn str::split_at* 908c430f90b const fn str::is_char_boundary 3804ceb5928 vectorized SliceContains dab8a07e0c6 s/SmartPointer/CoerceReferent/g be2e2520a8f fix a typo in documentation of pointer::sub_ptr() 4489ada2533 fix documentation of ptr::dangling() function beb0813c0f9 "innermost", "outermost", "leftmost", and "rightmost" don't need hyphens e5207dc3e2f Specialize `read_exact` and `read_buf_exact` for `VecDeque` 57241596b67 Rollup merge of #132031 - slanterns:rc_default, r=ibraheemdev cdf7373322d Rollup merge of #131707 - clarfonthey:constify-core-tests, r=thomcc a723e9945c0 Auto merge of #131929 - LaihoE:replace_default_capacity, r=joboet e4fc33d4c2b AIX use /dev/urandom for impl c0f78b0fd64 better default capacity for str::replace 6cb2df2e4f2 Rename Receiver -> LegacyReceiver 44957966850 refactor `Arc::default` 82498152f13 optimize `Rc::default` cd6cb9b77a8 Rollup merge of #131697 - ShE3py:rt-arg-lifetimes, r=Amanieu 9d53c3d831f Document PartialEq impl for OnceLock f03c8c01999 Rollup merge of #132003 - RalfJung:abi-compat-docs, r=traviscross 4066a64f143 Rollup merge of #130350 - RalfJung:strict-provenance, r=dtolnay bda4d9a08c4 update ABI compatibility docs for new option-like rules f215166548f move strict provenance lints to new feature gate, remove old feature gates f623dd3510b stabilize Strict Provenance and Exposed Provenance f6c9bdee93a fix docs 8ca8d1c2840 replace FindFirstFileW with FindFirstFileExW and apply optimization ec7fd656204 replace FindFirstFileW with FindFirstFileExW and regenerate bindings fe800fec874 Auto merge of #131948 - matthiaskrgr:rollup-c9rvzu6, r=matthiaskrgr cbce52d7930 Support lock() and lock_shared() on async IO Files 337589b47fe Rollup merge of #131921 - klensy:statx_all, r=ChrisDenton a18ec462803 Rollup merge of #131772 - GnomedDev:remove-proc_macro-todo, r=petrochenkov 2de2bb8c725 Auto merge of #131907 - saethlin:update-compiler-builtins, r=tgross35 27da9878375 Update `compiler-builtins` to 0.1.134 4926eaf8eb3 Rollup merge of #131919 - RalfJung:zero-sized-accesses, r=jhpratt 128a16b2582 Rollup merge of #131890 - printfn:precise-capturing-docs, r=traviscross 482e00e978e Rollup merge of #127462 - Ayush1325:uefi-env, r=joboet 5b58eaf4c04 Remove the Arc rt::init allocation for thread info 907235305db Auto merge of #131816 - Zalathar:profiler-feature, r=Kobzol 50b999587c3 replace STATX_ALL with (STATX_BASIC_STATS | STATX_BTIME) as former is deprecated e10007c801c zero-sized accesses are fine on null pointers c839b06e6f7 Update `use` keyword docs to describe precise capturing 52d741650e3 std: uefi: Use common function for UEFI shell ee906dc299f std: uefi: Add basic Env variables bcb8c74ac6d Auto merge of #131895 - jieyouxu:rollup-jyt3pic, r=jieyouxu ec7185ea142 Rollup merge of #126207 - devnexen:stack_overflow_libc_upd, r=joboet d490861f932 Auto merge of #131841 - paulmenage:futex-abstraction, r=joboet 321ed487b43 Revert using `HEAP` static in Windows alloc 9f4792a0c17 Rollup merge of #131866 - jieyouxu:thread_local, r=jhpratt 70a07c3e85c Rollup merge of #131858 - AnthonyMikh:AnthonyMikh/repeat_n-is-not-that-special-anymore, r=jhpratt 397c893fc1a Rollup merge of #131809 - collinoc:fix-retain-mut-docs, r=jhpratt 958ce90f8b5 Rollup merge of #131774 - thesummer:rtems-add-getentropy, r=joboet a02fe2c3ab7 Rollup merge of #130136 - GKFX:stabilize-const-pin, r=dtolnay b75a761783d Add entropy source for RTEMS ee0238f6983 Rollup merge of #131850 - lexeyOK:master, r=compiler-errors 2fb1b3123dc Rollup merge of #131823 - thesummer:bump-libc-0.2.160, r=workingjubilee bad79f7adeb Rollup merge of #131654 - betrusted-io:xous-various-fixes, r=thomcc 5c57b583a5e Avoid shadowing user provided types or type aliases in `thread_local!` 3d6e29ab956 remove outdated documentation for `repeat_n` 2925689b331 Auto merge of #131572 - cuviper:ub-index_range, r=thomcc 7e5438a1c0e Bump libc to 0.2.161 11e5ea4617e std::unix::stack_overflow::drop_handler addressing todo through libc update f7bd16a03cc Missing parenthesis 1df22fb2b27 Abstract the state type for futexes 704ed799ad7 Rollup merge of #131835 - ferrocene:amanjeev/add-missing-attribute-unwind, r=Noratrieb afedc50a999 Rollup merge of #131833 - c-ryan747:patch-1, r=Noratrieb 55231fc463a Auto merge of #130223 - LaihoE:faster_str_replace, r=thomcc e3b067b3d5c Do not run test where it cannot run 96406cc04ba Add must_use to CommandExt::exec ff3476a0445 Make `profiler_builtins` an optional dependency of sysroot, not std f94af194acf Remove TODO in proc_macro now `const_refs_to_static` is stable 31b63e6cd04 Fix predicate signatures in retain_mut docs bfca7d41a5f Win: Remove special casing of the win7 target for `std::fs::rename` 85ffa8b1c0d Auto merge of #131797 - matthiaskrgr:rollup-lzpze2k, r=matthiaskrgr ea93b310074 Partially stabilize const_pin 5f8ad4da356 Rollup merge of #131730 - zlfn:master, r=tgross35 354887191ca Auto merge of #131792 - matthiaskrgr:rollup-480nwg4, r=matthiaskrgr 828d995efd6 Rollup merge of #130822 - bjoernager:non-null-from-ref, r=dtolnay 0d4e8ae492a Auto merge of #131767 - cuviper:bump-stage0, r=Mark-Simulacrum 3fc0b3dd5ab Rollup merge of #131746 - slanterns:once_box_order, r=joboet 1e8ad2f6796 Rollup merge of #131712 - tgross35:const-lazy_cell_into_inner, r=joboet 67981579caa Auto merge of #131460 - jwong101:default-placement-new, r=ibraheemdev c38229a1748 update bootstrap configs 0a1c9a389b5 replace placeholder version 9f57bef95bb relax a memory order in `once_box` fa35f4afd1d Rollup merge of #131521 - jdonszelmann:rc, r=joboet 466bf5e0288 Rollup merge of #130568 - eduardosm:const-float-methods, r=RalfJung,tgross35 11cd5cf6239 Rollup merge of #129794 - Ayush1325:uefi-os-expand, r=joboet bc5df86d896 Refactor `floating` macro and nofloat panic message 1a571be0c2c Auto merge of #131723 - matthiaskrgr:rollup-krcslig, r=matthiaskrgr a5586b0b065 Rename debug! macro to impl_Debug! 10414806c3a Combine impl_int and impl_uint 3752402b7be Make some float methods unstable `const fn` e622fc2166b Auto merge of #131724 - matthiaskrgr:rollup-ntgkkk8, r=matthiaskrgr 153826df1d2 Rollup merge of #131706 - GKFX:fix-const-hacks, r=tgross35 e4f2156fb7f Rollup merge of #131496 - bjoernager:const-make-ascii, r=dtolnay 5882c0c737c Rollup merge of #130608 - YohDeadfall:cstr-from-into-str, r=workingjubilee 9ac4f2f95d7 Rollup merge of #131339 - HeroicKatora:set_ptr_value-documentation, r=Mark-Simulacrum 22d86de7dfe Rollup merge of #122670 - beetrees:non-unicode-option-env-error, r=compiler-errors 369b6ba1d85 Auto merge of #129458 - EnzymeAD:enzyme-frontend, r=jieyouxu b978d5a1ee0 Stabilise 'const_make_ascii' 53c92f4eb62 Add a `const_sockaddr_setters` feature ee2f48efb07 Mark LazyCell::into_inner unstably const 218ff376032 Run most core::num tests in const context too 0dbc1f1981c Fix two const-hacks 0c021dd31e7 `rt::Argument`: elide lifetimes ade0a318584 Rollup merge of #131384 - saethlin:precondition-tests, r=ibraheemdev 19e6f074d49 Rollup merge of #129424 - coolreader18:stabilize-pin_as_deref_mut, r=dtolnay ea6aac8e5cb Auto merge of #131672 - matthiaskrgr:rollup-gyzysj4, r=matthiaskrgr 509514b814e Remove allowing static_mut_refs lint abccf5647e1 uefi: Implement getcwd and chdir c42415a5ac8 Rollup merge of #131616 - RalfJung:const_ip, r=tgross35 38193837584 Rollup merge of #131274 - workingjubilee:stabilize-the-one-that-got-away, r=scottmcm 063b3704b3b Rollup merge of #130629 - Dirbaio:net-from-octets, r=tgross35 141506ad18f Rollup merge of #128967 - devnexen:get_path_fbsd_upd, r=joboet 33e03fd6b3b Auto merge of #126557 - GrigorenkoPV:vec_track_caller, r=joboet 91bd2b7faa6 Implement file_lock feature 5cfbd8c81d3 Auto merge of #131662 - matthiaskrgr:rollup-r1wkfxw, r=matthiaskrgr fb9c5627aed rename rcbox in other places as per review comments 4766cd1ad6a core/net: use hex for ipv6 doctests for consistency. 8d74490f6ba core/net: add Ipv[46]Addr::from_octets, Ipv6Addr::from_segments ee984d27511 Rollup merge of #131646 - RalfJung:unix-miri-fallbacks, r=joboet 3bdf19c47ed Rollup merge of #131644 - RalfJung:win-miri, r=joboet bba49a2235d library: xous: mark alloc as `FIXME(static_mut_refs)` 892e79c5b08 xous: ffi: correct syscall number for adjust_process 3442cd5a55b net: fix dead code warning bce378f44ee std: xous: add support for args and env 24bd165220d Auto merge of #125679 - clarfonthey:escape_ascii, r=joboet 3b457676728 unwind: update unwinding dependency to 0.2.3 c5430c3725e sys/unix: add comments for some Miri fallbacks 7e1a08f5cf0 remove outdated comment now that Miri is on CI e684bdf7ee2 sys/windows: remove miri hack that is only needed for win7 e39bacf911b switch unicode-data back to 'static' afc8c758b64 merge const_ipv4 / const_ipv6 feature gate into 'ip' feature gate a63aa65439a Rollup merge of #131418 - coolreader18:wasm-exc-use-stdarch, r=bjorn3 7ca353d0b8b Rollup merge of #131120 - tgross35:stabilize-const_option, r=RalfJung 883ad341c7d Fix bug where `option_env!` would return `None` when env var is present but not valid Unicode 42d5e10c195 Fix typo thing->thin referring to pointer 7b3fd7a4956 Stabilize `const_option` ed69c78bafa Rollup merge of #131617 - RalfJung:const_cow_is_borrowed, r=tgross35 bd165f78881 Rollup merge of #131503 - theemathas:stdin_read_line_docs, r=Mark-Simulacrum 5642d40a1fc remove const_cow_is_borrowed feature gate 670638a9e1e Rollup merge of #131233 - joboet:stdout-before-main, r=tgross35 96f90d58330 Rollup merge of #130954 - workingjubilee:stabilize-const-mut-fn, r=RalfJung ee2dc22798f std: fix stdout-before-main e8510a295d7 library: Stabilize `const_replace` a88242c16f3 library: Stabilize `const_ptr_write` aa24207c72e library: Stabilize `const_intrinsic_forget` 34ab578c4e2 Rollup merge of #131289 - RalfJung:duration_consts_float, r=tgross35 ceb368d23c7 Rollup merge of #130962 - nyurik:opts-libs, r=cuviper 0a84a7283fc Rollup merge of #124874 - jedbrown:float-mul-add-fast, r=saethlin 9e4e8603602 Avoid superfluous UB checks in `IndexRange` c704e4711bd Rollup merge of #131463 - bjoernager:const-char-encode-utf8, r=RalfJung 6cb3933ceeb Rollup merge of #131287 - RalfJung:const_result, r=tgross35 6cc8d77f299 Rollup merge of #131109 - tgross35:stabilize-debug_more_non_exhaustive, r=joboet d5cf193309a Rollup merge of #131065 - Voultapher:port-sort-test-suite, r=thomcc dedccb6f8ed intrinsics.fmuladdf{16,32,64,128}: expose llvm.fmuladd.* semantics 58bc5ed6e2c Single commit implementing the enzyme/autodiff frontend 51f966aa559 stabilize const_result 937aa27f792 stabilize duration_consts_float 167ffd21963 Rollup merge of #131512 - j7nw4r:master, r=jhpratt 35f52e0dcc9 rename RcBox in other places too 117da25fddd rename RcBox to RcInner for consistency c8798b0a188 Fixing rustDoc for LayoutError. 6f6ab06ce71 Rollup merge of #130741 - mrkajetanp:detect-b16b16, r=Amanieu 0fb4ec3445f Rollup merge of #130538 - ultrabear:ultrabear_const_from_ref, r=workingjubilee 21433dc4e07 uefi: process: Add args support 97ee4a0a3ec Use with_capacity(0) because we're reading the capacity later on cb282374592 Prefer `target_vendor = "apple"` on confstr 1e44a555110 use `confstr(_CS_DARWIN_USER_TEMP_DIR, ...)` as a `TMPDIR` fallback on darwin 7fc562007ce More clearly document Stdin::read_line 55d9736d66d Stabilise 'const_char_encode_utf8'; 83c42b0f038 allocate before calling T::default in >::default() 2a91b0947b8 allocate before calling T::default in >::default() eff75bfd171 rustc_target: Add sme-b16b16 as an explicit aarch64 target feature 27b3c9415e3 stdarch: Bump stdarch submodule 570eba59aef Clean up is_aligned_and_not_null 583b44726bb Add more precondition check tests 477dcdff413 Allow zero-size reads/writes on null pointers 08ad99df0ee Optimize escape_ascii 5fc0772514a Rollup merge of #131462 - cuviper:open_buffered-error, r=RalfJung 9b05ee59e9f Rollup merge of #131449 - nickrum:wasip2-net-decouple-fd, r=alexcrichton 7f892d733a1 Rollup merge of #131383 - AngelicosPhosphoros:better_doc_for_slice_slicing_at_ends, r=cuviper 97fe70ab55c Rollup merge of #130827 - fmease:library-mv-obj-save-dyn-compat, r=ibraheemdev 1e9da1c1f37 Add "not guaranteed to be equal" ac2282630b8 Mention allocation errors for `open_buffered` 475d4e2d046 Apply suggestions from code review ef90ffb653b Expand `ptr::fn_addr_eq()` documentation. 546c38a781f Library: Rename "object safe" to "dyn compatible" 2c869128102 Decouple WASIp2 sockets from WasiFd 9e465efb89a stabilize `{slice,array}::from_mut` 1543e70a39e Update library/std/src/sys/pal/unix/process/process_vxworks.rs 0507404c825 fix ref in process_vxworks.rs 9fcb8659a24 Update library/std/src/sys/pal/unix/process/process_unix.rs c48ebc3a36e Change a few `&Option` into `Option<&T>` 25287cb79e2 Use throw intrinsic from stdarch in wasm libunwind 70434ad76ce Stabilize Pin::as_deref_mut 7727df4e3ce Stabilize `isqrt` feature 27513367411 Add LowerExp and UpperExp implementations 5ff86617bcf Add docs about slicing slices at the ends a99f748a0dd cfg out checks in add and sub but not offset 07f7587c3e9 Add precondition checks to ptr::offset, ptr::add, ptr::sub 66c932d04d9 Rollup merge of #131308 - mati865:gnullvm-f16-f128, r=tgross35 bdac153b2dc Rollup merge of #128399 - mammothbane:master, r=Amanieu,tgross35 91f5fe4a881 liballoc: introduce String, Vec const-slicing 83e7c401719 Auto merge of #128651 - folkertdev:naked-asm-macro-v2, r=Amanieu 04cb48af872 Expand set_ptr_value / with_metadata_of docs e66795c2717 Rollup merge of #131335 - dacianpascu06:fix-typo, r=joboet f88cc6a4067 Rollup merge of #131307 - YohDeadfall:prctl-set-name-dbg-assert, r=workingjubilee dd09eb78662 grammar fix 11be67702f7 disallow `asm!` in `#[naked]` functions 9769205c7a7 implement `naked_asm` macro 35f65da8628 Rollup merge of #131316 - programmerjake:patch-4, r=Noratrieb f9203da2cd5 Auto merge of #131314 - tgross35:update-builtins, r=tgross35 24312a8f4c1 Fix typo in primitive_docs.rs 7394c4b2a52 Auto merge of #130540 - veera-sivarajan:fix-87525, r=estebank 8f45088402b Update `compiler-builtins` to 0.1.133 b46d8dd7c55 enable f16 and f128 on windows-gnullvm targets 4c7f32256cf Auto merge of #131302 - matthiaskrgr:rollup-56kbpzx, r=matthiaskrgr 2bd842042c5 Unbreak tidy b4760ccb577 Stabilize `std::io::ErrorKind::QuotaExceeded` d20e405bf9f Android: Debug assertion after setting thread name be3ffa8cac4 Rollup merge of #131281 - RalfJung:const-cell, r=Amanieu 8bb1ee7f32f Auto merge of #131221 - XrXr:bump-compiler-builtins, r=tgross35 b39b1968494 library: Stabilize const `MaybeUninit::assume_init_mut` 2902c6717a6 Add a Lint for Pointer to Integer Transmutes in Consts 70387688eef Rollup merge of #131256 - RalfJung:f16-f128-const, r=ibraheemdev 97fb3ee8657 Rollup merge of #131094 - joboet:lazy_once_box, r=ibraheemdev 7df9873d4f4 make Cell unstably const 02e0086245f move f16/f128 const fn under f16/f128 feature gate 4456a8e9f8b Stabilize `const_slice_split_at_mut` and `const_slice_first_last_chunk` 6ef918bfd46 Rollup merge of #131267 - okaneco:bufread_skip_until, r=tgross35 002aff62243 Rollup merge of #131105 - slanterns:literal_c_str, r=petrochenkov c447ed16c0f Rollup merge of #130403 - eduardosm:stabilize-const_slice_from_raw_parts_mut, r=workingjubilee 9a1479139f1 Update compiler-builtins to 0.1.132 0d8e8fa72fd Rollup merge of #131177 - workingjubilee:stabilize-const-mut-referees, r=tgross35 2352e4df8db Rollup merge of #130518 - scottmcm:stabilize-controlflow-extra, r=dtolnay 3476944c03a Stabilize `BufRead::skip_until` f7db8551c21 Auto merge of #130157 - eduardosm:stabilize-const_float_classify, r=RalfJung c92f0d92b4f Stabilize UnsafeCell::from_mut cc76a1e84e1 update libc version 49e475264ed std::fs::get_path freebsd update. 4fdc417a696 control libunwind linkage mode via `crt-static` on gnullvm targets 155a43a3bb0 Rollup merge of #131197 - EFanZh:avoid-emptyness-check-in-peekmut-pop, r=Amanieu ca82b43ade0 Avoid emptiness check in `PeekMut::pop` 0ab55e2caac Rollup merge of #131163 - JakenHerman:master, r=Nadrieril 93a7f9ecc9c Auto merge of #128711 - clarfonthey:default-iters-hash, r=dtolnay aef3003d7cb Add `get_line` confusable to `Stdin::read_line()` 1705e4415b4 impl Default for Hash{Map,Set} iterators that don't already have it f0f447749a6 Auto merge of #127912 - joboet:tls_dtor_thread_current, r=cuviper 8767c670b8b Auto merge of #131148 - Urgau:hashbrown-0.15, r=Amanieu 93a7c0614d9 library: Stabilize `const_slice_first_last` 1444aa5218f library: Stabilize `const_unsafecell_get_mut` 96fa2a83c59 library: Stabilize `const_ptr_as_ref` 8d7501c6d5b library: Stabilize `const_str_as_mut` 82cc93c1c9f library: Stabilize `const_str_from_utf8_unchecked_mut` 9d53381215c std: make `thread::current` available in all `thread_local!` destructors 0fc5822a0f1 Rollup merge of #131141 - RalfJung:mpmc-test, r=Amanieu ff77ec6c231 Update hashbrown to 0.15 and adjust some methods 4377a68209b mpmc doctest: make sure main thread waits for child threads 77bdee15aa6 Auto merge of #130829 - Urgau:option_array_transpose, r=ibraheemdev 26e4a46f72e Auto merge of #128204 - GuillaumeGomez:integers-opti, r=workingjubilee b9f727ed3e4 std: replace `LazyBox` with `OnceBox` 1779af6dac0 Stabilize `const_slice_from_raw_parts_mut` 408a6a911a1 Auto merge of #131111 - matthiaskrgr:rollup-n6do187, r=matthiaskrgr 6fc1d58bc81 Rollup merge of #130773 - bjoernager:master, r=thomcc 53d6d459048 Rollup merge of #130229 - RalfJung:ptr-offset-unsigned, r=scottmcm 0ee7327f0c1 Implemented FromStr for CString and TryFrom for String bd81c0d0206 Stabilize `debug_more_non_exhaustive` ceab9e55813 update `Literal`'s intro 462c5b56237 Auto merge of #131098 - GuillaumeGomez:rollup-kk74was, r=GuillaumeGomez 807a11c0eba Rollup merge of #131085 - RalfJung:miri-slow-test, r=tgross35 badfd7c7207 Auto merge of #126839 - obeis:mpmc, r=Amanieu c33d6bfaf1c Remove the need to provide the maximum number of digits to `impl_Display` macro 191bdd91f09 Simplify `impl_Display` macro 91991304606 Small optimization for integers Display implementation a91a8abe10a make test_lots_of_insertions test take less long in Miri 29a86e6555c Enable `f16` tests on non-GNU Windows d632475da3e Rollup merge of #130966 - RalfJung:ptr-metadata-const-stable, r=scottmcm dfeea4d4acb Rollup merge of #130961 - tgross35:f16-x86-apple, r=thomcc 9d8e2a9feee Rollup merge of #130914 - compiler-errors:insignificant-dtor, r=Amanieu eabe06c6c6b Rollup merge of #129638 - nickrum:wasip2-net, r=alexcrichton 82e0a5a93f4 Win: Add test cases for renaming a directory while the target file is opened and for renaming over a non-empty directory 71f6c898184 Win: Use `FILE_RENAME_FLAG_POSIX_SEMANTICS` for `std::fs::rename` if available 6cb925be3f5 Add multi-producer, multi-consumer channel (mpmc) 687e73e77b4 Port sort-research-rs test suite Rust stdlib tests 26bed78c77e Rollup merge of #130972 - RalfJung:const_cell_into_inner, r=dtolnay 2732add8cc3 Rollup merge of #129003 - Voultapher:improve-ord-docs, r=workingjubilee d9ceb60b1e2 Rollup merge of #123932 - adamse:global-alloc-safety-preconds-positive, r=tgross35 a290f48d0fd Rollup merge of #130931 - GuillaumeGomez:standalone-crate, r=notriddle c9682ee3d6e Rename doctest attribute `standalone-crate` into `standalone_crate` for coherency 9eb1e61f483 Rollup merge of #130743 - YohDeadfall:net-nonblocking-doc, r=Mark-Simulacrum 46a493041e6 Rollup merge of #130416 - BatmanAoD:130122-sort-by-docs, r=Mark-Simulacrum 0a8b5bf6e5d Remove duplicate section 9b240b2fca0 Auto merge of #128321 - BatmanAoD:catch-unwind-doc-update, r=Mark-Simulacrum d1d9de4a2f0 Fix std tests for wasm32-wasip2 target 6225e4b121b Hook up std::net to wasi-libc on wasm32-wasip2 target b6e91008337 Auto merge of #123778 - jhorstmann:optimize-upper-lower-auto-vectorization, r=the8472 62a6622e9b0 Enable `f16` tests on x86 Apple platforms 4342952b20a Auto merge of #129385 - tgross35:more-platforms-enable-f16, r=Mark-Simulacrum d47a4b2f29a Auto merge of #130792 - tgross35:update-builtins, r=Amanieu ab5e52738c4 Rename `standalone` doctest attribute into `standalone-crate` 6aca0fffb71 Update compiler_builtins to 0.1.130 69463753c61 Rollup merge of #128778 - RalfJung:atomic-read-read-races, r=Mark-Simulacrum 86ca98eff9f Auto merge of #130964 - matthiaskrgr:rollup-suriuub, r=matthiaskrgr 7f373af1760 Further clarificarion for atomic and UnsafeCell docs: fd69ecdadef allow mixed-size atomic reads 100f44388da atomics: allow atomic and non-atomic reads to race 9d87f95b450 stabilize const_cell_into_inner 9868670b3eb make ptr metadata functions callable from stable const fn 116b3ef01ae Auto merge of #130897 - workingjubilee:dump-hexes-with-class, r=thomcc 65b87616d51 Rollup merge of #130922 - tyilo:udp-unspecified, r=ibraheemdev 154007bb5fc Rollup merge of #125404 - a1phyr:fix-read_buf-uses, r=workingjubilee b3c3202be8f Update Unicode escapes; fc0f1c738ce Enable `f16` on platforms that were missing conversion symbols 37d90ffe42b Auto merge of #130946 - matthiaskrgr:rollup-ia4mf0y, r=matthiaskrgr dd10667db6b Rollup merge of #130926 - ChrisDenton:cc-1-1-22, r=tgross35 78ec41e4f62 Rollup merge of #129087 - slanterns:option_get_or_insert_default, r=dtolnay c17f4b74459 Mark some more smart pointers as insignificant bb674b19b59 Mark some more types as having insignificant dtor eea1e58cb24 Add 'from_ref' and 'from_mut' constructors to 'core::ptr::NonNull'; cf61167bd3a Update Cargo.lock 60f783370eb Apply review feedback b00703e4d00 Apply round 1 of review comments 590c2d1ac5d Fix mistake in example 5489bb31d0a Improve Ord docs 98061c9d685 Reference UNSPECIFIED instead of INADDR_ANY in join_multicast_v4 3f5c3820e2f Rollup merge of #130892 - tgross35:library-cargo-update, r=Noratrieb 7b3d03d3d69 Rollup merge of #130875 - folkertdev:naked-asm-bootstrap, r=tgross35 e7469ec94a2 Rollup merge of #130846 - ChrisDenton:revert-break, r=Noratrieb 36bb7fe391a Rollup merge of #130313 - c410-f3r:unlock-rfc-2011, r=thomcc 024fc9248cd Rollup merge of #130880 - RalfJung:const-hack, r=scottmcm 31c7ef7d5cf Rollup merge of #130861 - cuviper:sun-path-offset, r=ibraheemdev a7d5afe437f Rollup merge of #130845 - RalfJung:utf8chunk, r=tgross35 d74393617e6 Rollup merge of #130279 - theemathas:manually-drop-docs, r=thomcc,traviscross 68614067b5f library: Compute `RUST_EXCEPTION_CLASS` from native-endian bytes c071b26a90e Partially update `library/Cargo.lock` 5162f5c7c3f Add `sun_path` to the fake doc `sockaddr_un` d397e645267 add missing FIXME(const-hack) 7825964c112 Add `[Option; N]::transpose` 5941eed5462 update `compiler_builtins` to `0.1.126` 044e998093d add a bootstrap variant of `naked_asm` 0cf3fdbcac7 Stabilize the `map`/`value` methods on `ControlFlow` c0a7c80d880 Use `&raw` in the standard library 04653fe0b15 Use `mem::offset_of!` for `sockaddr_un.sun_path` b046a8a8c76 Rollup merge of #130842 - Noratrieb:tracking-issue-inprogress, r=jieyouxu d43b29b919b Rollup merge of #130832 - RalfJung:sort-cfg-mess, r=workingjubilee c83aae73114 Rollup merge of #130819 - bjoernager:char-must-use-len-utf, r=Noratrieb 89c0fa234ad Rollup merge of #130811 - RalfJung:random, r=joboet ad13f237867 Revert Break into the debugger on panic (129019) 4ac32923ddb Utf8Chunks: add link to Utf8Chunk 5138ffaaa77 Add tracking issue for io_error_inprogress 0b59139d38c fix some cfg logic around optimize_for_size and 16-bit targets 127d2e8adde Auto merge of #130816 - matthiaskrgr:rollup-jy25phv, r=matthiaskrgr cb64cdc4590 Add 'must_use' attribute to 'char::len_utf8' and 'char::len_utf16'; cb09110485c Rollup merge of #130810 - kromych:master, r=workingjubilee dc40c8bf4ef Rollup merge of #130595 - no1wudi:master, r=ibraheemdev e1874d9a577 Rollup merge of #130549 - biabbas:riscv32_wrs_vxworks, r=nnethercote defa29832bf add link from random() helper fn to extensive DefaultRandomSource docs f36419f4d51 Auto merge of #130803 - cuviper:file-buffered, r=joshtriplett d1093f3be1c Don't trap into the debugger on panics under Linux 40946e3f2d7 Rollup merge of #130789 - aviramha:add_inprogress, r=Noratrieb 2692a232d36 Rollup merge of #130788 - tgross35:memchr-pinning, r=Noratrieb,Mark-Simulacrum 5d2cfb25a2b Add a tracking issue for `file_buffered` 50714cc945d Dogfood `feature(file_buffered)` 9cb48e28cf8 Mark 'get_mut' and 'set_position' in 'std::io::Cursor' as const; f3a86975c65 Pre-allocate buffers in `File::open_buffered` and `create_buffered` b29d2942abf Add `File::open_buffered` and `create_buffered` 5e83d67cb02 Auto merge of #129587 - Voultapher:opt-for-size-variants-of-sort-impls, r=cuviper 2c831533aa4 add InProgress ErrorKind gated behind io_error_inprogress feature a1a147089d5 Pin memchr to 2.5.0 in the library rather than rustc_ast a466036a4af Auto merge of #130738 - bjoernager:const-make-ascii, r=jhpratt 4c056e0be29 Initial std library support for NuttX c226cfa4cee Mark and implement 'make_ascii_uppercase' and 'make_ascii_lowercase' in '[u8]' and 'str' as const; a58fa0a7524 Rollup merge of #130762 - RalfJung:const_intrinsic_copy, r=dtolnay f6e152b11e4 Rollup merge of #129545 - notriddle:notriddle/toolbar-v2, r=GuillaumeGomez eb17f5faa52 Add a comment to `Read::read_buf` 97cf0c4c229 Add tests a5e6e41a327 Fix `io::default_read_to_end` uses of `read_buf` 9193052d3bb Fix `io::BufReader` uses of `read_buf` d3cf0e764fa Fix `io::Take::read_buf` 48a5a4f6e5d stabilize const_intrinsic_copy 4a432e3a513 Add fast path for ascii to ascii in str::replace c8066ecd118 Fix up standard library intro 43020f51f23 Clarifications for set_nonblocking methods 78708e35409 Improve autovectorization of to_lowercase / to_uppercase functions 4fd08720f35 random: add tracking issue, address other comments fedfe246a7c std: switch to faster random sources on macOS and most BSDs aa78f3c8f20 std: implement the `random` feature 872508b4949 Rollup merge of #130723 - D0liphin:master, r=workingjubilee 1e08ef087dd Rollup merge of #130713 - bjoernager:const-char-make-ascii, r=Noratrieb 32625db2734 Rollup merge of #130659 - bjoernager:const-char-encode-utf16, r=dtolnay 8f8206670dc Rollup merge of #129550 - kornelski:boxasstr, r=joshtriplett,dtolnay 9c10719bb98 Reformat using the new identifier sorting from rustfmt b28dfbe17ee reword edge-conditions documentation on all slice 'sort' functions; resolves #130122 8bb091eeb80 Add test for `available_parallelism()` 8d616ae81b1 Mark 'make_ascii_uppercase' and 'make_ascii_lowercase' in 'u8' as const; Rename 'const_char_make_ascii' feature gate to 'const_make_ascii'; 5b8acc49166 Rollup merge of #130692 - RalfJung:result-flatten, r=Noratrieb 4371948d32f Rollup merge of #130670 - the8472:read-to-end-heuristics, r=ChrisDenton 4ed55ca812d Rollup merge of #130658 - EqualMa:patch-1, r=scottmcm 454ec49690a Auto merge of #130697 - bjoernager:const-char-make-ascii, r=dtolnay 338993ec728 Mark 'make_ascii_uppercase' and 'make_ascii_lowercase' in 'char' as const; 1d281c4e64f make unstable Result::flatten a const fn f62b0ea04db Rollup merge of #130653 - RalfJung:result-abi-compat, r=traviscross 664f99590d9 Rollup merge of #130408 - okaneco:into_lossy_refactor, r=Noratrieb 8ce63eb497e wait for two short reads before uncapping the max read size 0a65192a806 Mark and implement 'char::encode_utf16' as const; Rewrite 'encode_utf16_raw'; ac8a657b858 Fix docs of compare_bytes f3a2004991f ABI compatibility: mention Result guarantee 59fda41f7e0 Reword ManuallyDrop+Box interaction fccac266b62 Rollup merge of #129718 - lolbinarycat:remove_dir-docs, r=Noratrieb f9c1843e840 Avoid re-validating UTF-8 in `FromUtf8Error::into_utf8_lossy` edc1a710b26 Auto merge of #130631 - GuillaumeGomez:rollup-jpgy1iv, r=GuillaumeGomez c89636a9f9c Remove double spaces 7f32604963e Rollup merge of #130624 - theemathas:vec_as_non_null, r=Noratrieb 1e2023c28d7 Rollup merge of #130611 - bjoernager:const-char-encode-utf8, r=dtolnay bb5d36e3b17 Rollup merge of #130526 - eholk:pin-reborrow, r=compiler-errors 3c271ad6709 Rollup merge of #128209 - beetrees:no-macos-10.10, r=jieyouxu cad8f33df7e Auto merge of #124895 - obeis:static-mut-hidden-ref, r=compiler-errors ac4082bd92f Add `Vec::as_non_null` a9463ea49bd Address diagnostics regression for 'const_char_encode_utf8'; ad5a36c222c Allow unused unsafe for vxworks in alligned_malloc to resolve build errors 27cc81fcead [Clippy] Remove final std paths for diagnostic item ab9c4d510fb Allow shortening reborrows 37b42e614b3 Add `#[track_caller]` to allocating methods of `Vec` & `VecDeque` 07eddbbffbe Rollup merge of #130554 - ShE3py:unsupported-exitcode, r=Noratrieb 7fc176d33ff Rollup merge of #130553 - GnomedDev:remove-clippy-paths, r=compiler-errors 7795ff050f7 Rollup merge of #128001 - Krappa322:master, r=scottmcm e1d453356f2 Add str.as_str() for easy dereferencing of Box 4d368ba0d77 `pal::unsupported::process::ExitCode`: use an `u8` instead of a `bool` 4f54973b0c9 [Clippy] Swap `open_options` to use diagnostic items instead of paths 1d21c3cae81 [Clippy] Swap `iter_over_hash_type` to use diagnostic items instead of paths 2f960774f27 [Clippy] Swap `non_octal_unix_permissions` to use diagnostic item instead of path bb8d0378236 [Clippy] Swap `unnecessary_owned_empty_strings` to use diagnostic item instead of path c72d6d7a320 [Clippy] Swap `manual_strip` to use diagnostic items instead of paths 8569e98afae [Clippy] Swap `unnecessary_to_owned` to use diagnostic item instead of path de7010272d0 [Clippy] Swap `instant_subtraction` to use diagnostic item instead of path ff592f26cdc [Clippy] Swap `waker_clone_wake` to use diagnostic item instead of path 320af931f7a [Clippy] Swap `filter_map_bool_then` to use diagnostic item instead of path 3077b359cd5 [Clippy] Swap `manual_while_let_some` to use diagnostic items instead of paths b1e8dfef574 [Clippy] Swap `repeat_vec_with_capacity` to use diagnostic item instead of path b7715f255c5 [Clippy] Swap `VecArgs::hir` to use diagnostic items instead of paths 903f4bec157 [Clippy] Swap `single_char_add_str`/`format_push_string` to use diagnostic items instead of paths bb0ce14d676 [Clippy] Swap `manual_main_separator_str` to use diagnostic item instead of path 558f16e330b [Clippy] Swap `redundant_clone` to use diagnostic items instead of paths 2999754c67f [Clippy] Swap `float_equality_without_abs` to use diagnostic items instead of paths 7bb3d993946 [Clippy] Swap `option_as_ref_deref` to use diagnostic items instead of paths 56329f5eac2 [Clippy] Swap `lines_filter_map_ok` to use a diagnostic item instead of path 44c8aedea7d [Clippy] Swap `map_entry` to use diagnostic items instead of paths 8e65cbcc54b Auto merge of #130547 - workingjubilee:rollup-tw30khz, r=workingjubilee bea06d567cd Auto merge of #130511 - bjoernager:const-char-encode-utf8, r=dtolnay ecc8d2963fa run `x.py fmt` effd4fdd42b remove feature attributes as const_maybe_uninit_as_mut_ptr is stabilized 547f1215da2 stabilize `const_maybe_uninit_as_mut_ptr` 5324cf35cd3 Mark and implement 'char::encode_utf8' as const. 3c15b76ee38 Rollup merge of #130522 - GnomedDev:clippy-manual-retain-paths, r=compiler-errors c128f3c47ca Rollup merge of #130513 - shekhirin:fs-write-doc-comment, r=cuviper 9cb08464ae5 Rollup merge of #130487 - cuviper:min-llvm-18, r=nikic ef3a5890796 Rollup merge of #130476 - workingjubilee:more-lazy-methods-take-2, r=Amanieu debf86ad310 Rollup merge of #129934 - ChrisDenton:remove-dir-all3, r=Amanieu 22b489e1d54 Rollup merge of #97524 - ibraheemdev:thread-raw, r=ibraheemdev 13a87bacca9 Revert "Add a hack to prevent proc_macro misopt in CI" 013e59bca3b Begin experimental support for pin reborrowing bd035503ecb library: Call it really_init_mut to avoid name collisions 88be3380b2b library: Destabilize Lazy{Cell,Lock}::{force,deref}_mut 73533102d6e [Clippy] Swap `manual_retain` to use diagnostic items instead of paths 767dbccc17f Auto merge of #130497 - saethlin:alloc-zeroed-is-unstable, r=bjorn3 53af607fd60 Clarify docs for std::fs::File::write 019c0ca19d0 Auto merge of #129491 - StackOverflowExcept1on:master, r=m-ou-se 413357d8e3b Auto merge of #129845 - scottmcm:redo-layout, r=Noratrieb d04eb238682 Take more advantage of the `isize::MAX` limit in `Layout` fd1b5ed2f25 read_volatile __rust_no_alloc_shim_is_unstable in alloc_zeroed 6870242bced Rollup merge of #130481 - krtab:clamp_partial_ord, r=cuviper 23c58d248ac Auto merge of #130483 - matthiaskrgr:rollup-q1r0g0y, r=matthiaskrgr ce114235121 Remove uneeded PartialOrd bound in cmp::Ord::clamp 71efa51411a Rollup merge of #130467 - RalfJung:miri-sync, r=RalfJung 3c043e6ba11 Rollup merge of #129674 - matthewpipie:rc-arc-new-cyclic-in, r=dtolnay 1c638bb51de Implement ACP 429: add `Lazy{Cell,Lock}::get[_mut]` and `force_mut` 34a560c4af4 Rollup merge of #128535 - mmvanheusden:master, r=workingjubilee 16f1377bbd8 Auto merge of #130145 - fee1-dead-contrib:repeatn, r=lcnr,workingjubilee c78a54a3bab Merge from rustc f96d83585cd Rollup merge of #130448 - alilleybrinker:master, r=workingjubilee d9fc5558207 Update library/alloc/src/sync.rs 44a398cef1e Auto merge of #127633 - SamuelMarks:eq-exit-code, r=dtolnay a320a09daf8 fix: Remove duplicate `LazyLock` example. 8b3ccad0852 Rollup merge of #127879 - kornelski:bad-pointer-printf, r=workingjubilee d586f738ac3 Merge from rustc 2f3fb000074 Auto merge of #130220 - RalfJung:float-classify, r=workingjubilee 3f46777868a update docs for `catch_unwind` & related funcs 4902f2db594 Rollup merge of #130339 - CAD97:unwind-choice, r=dtolnay 9be03c8ed1d simplify abort_unwind f3be0f8b9ad Rollup merge of #129439 - okaneco:vec_string_lossy, r=Noratrieb 92d3f3d1f0f Rollup merge of #130381 - workingjubilee:sometimes-code-really-is-self-descriptive, r=Noratrieb 05aeed218cf Rollup merge of #130118 - RalfJung:unwrap_unchecked, r=Noratrieb 9ab1d907fa1 Rollup merge of #129195 - RalfJung:const-mut-refs, r=fee1-dead 7188c4321cd also stabilize const_refs_to_cell f467b82c238 const_refs_to_cell: dont let mutable references sneak past the interior mutability check 6a77ac668b1 stabilize const_mut_refs 1c560f43c9a library: Compute Rust exception class from its string repr fa51b5ea911 Rollup merge of #130214 - RalfJung:zeroed, r=Mark-Simulacrum 4ac3a1c504b Rollup merge of #130061 - theemathas:box_vec_non_null, r=MarkSimulacrum,workingjubilee cff87aba46a Rollup merge of #130042 - lolbinarycat:bufreaker_peek_eof, r=Amanieu a48fca9f991 Add tracking issue number for `box_vec_non_null` f6f4a7cf05f std::net: Solaris supports `SOCK_CLOEXEC` as well since 11.4. de75bbceebf Rollup merge of #130290 - passcod:stabilise-entry-insert, r=ChrisDenton aaf695dd397 Rollup merge of #130268 - RalfJung:simd-shuffle-idx-vector, r=compiler-errors 949eaa7ce4d simd_shuffle: require index argument to be a vector cffd25d6bd4 Rollup merge of #130053 - glowcoil:next_if-docs, r=jhpratt d41974bec09 add std::panic::abort_unwind eb5f2c72506 add core::panic::abort_unwind bb6edf38b6d Merge from rustc aee905f1679 Rustfmt f8cdfb49fe3 [`cfg_match`] Generalize inputs 1cdee4a01fa Fix awkward wording. 96102fa1c62 Address WaffleLapkin's comments 740405835f5 Update tests for hidden references to mutable static f67920aaeee Rollup merge of #130245 - RalfJung:miri-alloc-backtrace, r=Amanieu 3c6923d1a4b Stabilize entry_insert b1c955dd4ae Auto merge of #130281 - matthiaskrgr:rollup-1b2ibs8, r=matthiaskrgr 37f4e897c4a Rollup merge of #130101 - RalfJung:const-cleanup, r=fee1-dead 70a4ca0fa73 Document subtleties of `ManuallyDrop` 640bff91ab4 Stabilize `const_float_classify` 52a09b425a9 Auto merge of #129992 - alexcrichton:update-compiler-builtins, r=tgross35 f0ad90654d8 also update the wrapping_ docs to use similar wording c4d7d4d702d Rollup merge of #130160 - Scripter17:fix-slice-first_mut-doc, r=Amanieu bb6f08489cd Rollup merge of #125060 - ChrisJefferson:pathbuf-doc, r=workingjubilee 318dc4ab1ef simplify float::classify logic 82d354cdd4e Fixup docs for PathBuf 793ca87cbc9 Expand PathBuf documentation 4d921cf0657 Merge from rustc 5b1268a7ead Auto merge of #130183 - Marcondiro:unicode-16.0.0, r=Manishearth 66c370fae35 Rollup merge of #130248 - nyurik:fix-129895, r=workingjubilee 189d929afc9 Rollup merge of #130168 - juliusl:pr/fix-win-fs-change-time-links, r=ChrisDenton 97dd605c7a5 Rollup merge of #130077 - madsmtm:watchos-arm-unwind, r=workingjubilee 485dd7483d3 Rollup merge of #129835 - RalfJung:float-tests, r=workingjubilee 514fcf1f4c4 Rollup merge of #129696 - RalfJung:stdarch, r=Amanieu 9d13155ce61 Limit `libc::link` usage to `nto70` target only, not NTO OS eb24b39481b various updates based on review b4461d2ebae make basic allocation functions track_caller in Miri for nicer backtraces 3ac337005a5 chore: remove struct details 82f64c9cb6d Rollup merge of #130207 - GrigorenkoPV:ERROR_CANT_RESOLVE_FILENAME, r=ChrisDenton fa1412dfb18 Rollup merge of #130206 - GrigorenkoPV:WSAEDQUOT, r=ChrisDenton 85d1bd2bb5d Rollup merge of #129866 - root-goblin:patch-1, r=workingjubilee bb43230de39 docs: remove struct info a01b06b001b ptr::add/sub: these are *not* equivalent to offset(count as isize) e1ed3716ec7 update stdarch 9fe6ce22cbe MaybeUninit::zeroed: mention that padding is not zeroed 60a0e4f4867 clean up internal comments about float semantics af15065f23e these tests seem to work fine on i586 these days c24e32e4d1c Auto merge of #129403 - scottmcm:only-array-simd, r=compiler-errors 63d6af9eaad Stabilize `std::io::ErrorKind::CrossesDevices` 5ee153c725c Clarify docs for std::collections aa22c85e938 Map `ERROR_CANT_RESOLVE_FILENAME` to `ErrorKind::FilesystemLoop` c2c5620c1ad Map `WSAEDQUOT` to `ErrorKind::FilesystemQuotaExceeded` dfc2e19ea8f Auto merge of #130025 - Urgau:missing_docs-expect, r=petrochenkov db0a6b4e86d Bump unicode printable to version 16.0.0 55886eb3893 Bump unicode_data to version 16.0.0 8776fe2b137 Auto merge of #130179 - workingjubilee:rollup-l78cv44, r=workingjubilee dd7ea0fa569 Ban non-array SIMD 1d14839e50f Rollup merge of #130164 - RalfJung:const_ptr_as_ref, r=dtolnay 1ba3a861af0 Rollup merge of #130146 - folkertdev:bootstrap-naked-asm, r=Amanieu 30eb156708b Rollup merge of #130132 - sunshowers:illumos-sigsegv, r=Noratrieb 8601a01f38d Rollup merge of #128316 - GrigorenkoPV:io_error_a_bit_more, r=dtolnay cbf3a1686cd Auto merge of #129778 - RalfJung:interp-lossy-typed-copy, r=saethlin 4704b69e082 chore: removing supporting links in favor of existing doc-comment style 5860f85eb00 maint: update docs for change_time ext and doc links b6af9696059 Rollup merge of #130154 - okaneco:stabilize_char_min, r=cuviper f6e5f3919cf Rollup merge of #130067 - madsmtm:clean-up-fs-test, r=ChrisDenton fd6024d027e move const fn with a null check into const_ptr_is_null gate c054cce2f80 move some const fn out of the const_ptr_as_ref feature 8d65b5be720 Fix slice::first_mut docs pointer -> reference 1f1b02e5b20 Stabilize `char::MIN` c8ef6fb582e fix UB in a test e8941c7cad3 Add missing `#[allow(missing_docs)]` on hack functions in alloc d0fb544c266 `RepeatN`: use MaybeUninit 0fe80cdf90f bootstrap `naked_asm!` for `compiler-builtins` 4d3a631a171 Rollup merge of #130115 - eduardosm:needless-returns-libs, r=workingjubilee 1f415495d52 Rollup merge of #130107 - RalfJung:const-ptr-is-null, r=oli-obk e9bd7fe937e Rollup merge of #130090 - RalfJung:result-copied, r=Noratrieb d11512d5b64 Rollup merge of #130087 - RalfJung:option-const-iter, r=workingjubilee b4c3ee97655 [illumos] enable SIGSEGV handler to detect stack overflows 7b560790331 remove const_slice_index annotations, it never had a feature gate anyway 5220807e883 add FIXME(const-hack) 07cd28fc5ac move Option::unwrap_unchecked into const_option feature gate a680f3be08c Remove needless returns detected by clippy in libraries 80015775711 const: make ptr.is_null() stop execution on ambiguity 087c340dcc8 Option, Result: put the &mut variants of 'copied' under the same feature as the '&' variants 756c77f1e83 Auto merge of #130002 - orlp:better-div-floor-ceil, r=thomcc 04636eeafd2 Auto merge of #129019 - kromych:master, r=workingjubilee 4846a585623 Fix linking error when compiling for 32-bit watchOS 0dd97efa71d remove pointless rustc_const_unstable on trait impls 5358066ed91 add some FIXME(const-hack) 55e4cc30915 Auto merge of #130091 - matthiaskrgr:rollup-kalu1cs, r=matthiaskrgr a7efbd1e9b7 Rollup merge of #130047 - ChrisDenton:win-dbghelp, r=wesleywiser 2a02cdd392c Rollup merge of #130046 - RalfJung:const_str_as_mut, r=dtolnay aefe9d4e552 Rollup merge of #129555 - RalfJung:const_float_bits_conv, r=dtolnay da098156e3f Auto merge of #129941 - BoxyUwU:bump-boostrap, r=albertlarsan68 1c9b822230f make Result::copied unstably const 07177378a6c remove 'const' from 'Option::iter' f4f84a69712 str: make as_mut_ptr and as_bytes_mut unstably const 66c5236bfa6 restate GlobalAlloc method safety preconditions in terms of what the caller has to do for greater clarity 2d3539170ae Remove now redundant check in symlink_hard_link test d3d47a73a9b Add `NonNull` convenience methods to `Vec` a247b553d94 Add `NonNull` convenience methods to `Box` 711ec568747 fix doc comments for Peekable::next_if(_eq) a83a94b629c Remove duplicate impl d7e8cb2dfe7 remove the Clone requirement 73a728ba901 Win: Add dbghelp to the list of import libraries 38d07e34ea7 properly handle EOF in BufReader::peek 23e25bdc488 [library/std/src/process.rs] Remove `Eq` `derive` dc28cf0f15a Adjust doc comment of Condvar::wait_while 8b2b60d9472 Rollup merge of #129963 - rjooske:fix/inaccurate_to_string_lossy_doc, r=workingjubilee ae82edffaad Auto merge of #129999 - matthiaskrgr:rollup-pzr9c8p, r=matthiaskrgr 9d41f980027 Break into the debugger (if attached) on panics (Windows, macOS, Linux, FreeBSD) d2124dfa85c better implementation of signed div_floor/ceil f7013c27d9d Rollup merge of #129947 - LiterallyVoid:duration-docs-digit-separators, r=tgross35 138ede02d88 Rollup merge of #129653 - RalfJung:addr-of-read-only, r=scottmcm bea58a90316 Rollup merge of #129938 - chancancode:patch-1, r=thomcc 5020a1f9cb1 [library/std/src/process.rs] Update docstring with @joshtriplett's replacement text 00c22d41ff2 Update compiler-builtins to 0.1.125 9b46fbf8a69 update cfgs f2ba4e975b9 Rollup merge of #129919 - kevinmehall:waker-getters, r=dtolnay 3909f83c377 Rollup merge of #127021 - thesummer:1-add-target-support-for-rtems-arm-xilinx-zedboard, r=tgross35 377688aa222 Rollup merge of #101339 - the8472:ci-randomize-debug, r=Mark-Simulacrum da00a9a4512 Use non-overlapping swap for inner heapsort loop 7fd9546e3fb Select tiny sorts for 16-bit platforms fa84101fdc6 Shrink heapsort further by combining sift_down loops fdfc09e7da1 Drop bubble_sort d6e5c6063d7 fix: correct {Path,OsStr}::to_string_lossy() docs f34dd285900 Remove macOS 10.10 dynamic linker bug workaround 2c24015c498 docs: add digit separators in `Duration` examples e151f7227d1 replace placeholder version f6277f09efc Update marker.rs b6bf3984271 Update marker.rs dae2ea6f1e0 Update marker.rs 9cbb5156137 Update marker.rs 7d26aaee86c Elaborate on deriving vs implementing `Copy` 97c31f275d9 Win: Open dir for sync access in remove_dir_all dbdb850884a More robust extension checking 2734b8aaec1 Port std library to RTEMS bf0415eb794 Rollup merge of #129916 - tshepang:basic-usage, r=ChrisDenton a8777717c4f Rollup merge of #129913 - saethlin:l4re-read-buf, r=Noratrieb 30735e927c4 Rollup merge of #129885 - cuishuang:master, r=scottmcm c6732b7f925 Rollup merge of #129800 - ChrisDenton:remove-dir-all2, r=Amanieu f7f38870e80 Add `Waker::new` and `LocalWaker::new` 467de59f118 Stabilize waker_getters fd73934e617 Move the `data` and `vtable` methods from `RawWaker` to `Waker` b743e1a2b33 process.rs: remove "Basic usage" text where not useful 51e8f514d32 Rollup merge of #129907 - saethlin:solid-io-error, r=WaffleLapkin fd1c0f0271c Rollup merge of #129892 - oskgo:clarify-slice-from-raw, r=RalfJung 16af9cef028 Rollup merge of #129890 - alex:patch-1, r=workingjubilee 7cdc5bf0cf2 Rollup merge of #129856 - RalfJung:compiler_fence, r=thomcc e5c1a6b8e53 Rollup merge of #129748 - RalfJung:box-validity, r=workingjubilee fa7f72571d5 Add missing read_buf stub for x86_64-unknown-l5re-uclibc a726b1c64d6 Fix compile error in solid's remove_dir_all ab45317ff39 clarify language around non-null ptrs in slice::raw 50e88bd4dd9 Remove stray word in a comment c8f10ea1259 Auto merge of #129873 - matthiaskrgr:rollup-bv849ud, r=matthiaskrgr b80b88e707b chore: remove repetitive words 7144d457299 Rollup merge of #129804 - ranger-ross:fixed-documentation-typos, r=Noratrieb 24d514ed7f1 Rollup merge of #129793 - lolbinarycat:doc-missing-newlines, r=workingjubilee 36dd3904bd5 Auto merge of #129063 - the8472:cold-opt-size, r=Amanieu 04dc3f3b055 add extra linebreaks so rustdoc can identify the first sentence 589f33022ae compiler_fence documentation: emphasize synchronization, not reordering ee96bfc9fe4 stabilize const_float_bits_conv dde28108c95 tweak wording regarding Box validity 8d193e1a2f9 Auto merge of #127897 - nyurik:add-qnx-70-target, r=saethlin 8a25c13eb3a Rollup merge of #129832 - eduardosm:stray-dot, r=jhpratt 3d63d0c8603 Rollup merge of #129207 - GrigorenkoPV:elided-is-named, r=cjgillot 8b1052c96ff Rollup merge of #128641 - Konippi:standardize-duplicate-processes-in-parser, r=scottmcm 6629248313e Rollup merge of #128495 - joboet:more_memcmp, r=scottmcm 88ded364cec when -Zrandomize-layout is enabled disable alloc test testing internal struct sizes 007b333db16 Auto merge of #129831 - matthiaskrgr:rollup-befq6zx, r=matthiaskrgr 6d44a3a8c63 Remove stray dot in `std::char::from_u32_unchecked` documentation f3c5ce1a16d Rollup merge of #129826 - Alcaro:patch-1, r=workingjubilee 9268b032d06 Rollup merge of #129650 - Zalathar:profiler-builtins, r=Mark-Simulacrum 0e237a45e46 Update mod.rs f41bcabd1e1 Rollup merge of #129785 - RalfJung:miri-sync, r=RalfJung b8626897320 Rollup merge of #129730 - RalfJung:float-arithmetic, r=workingjubilee cc5af888af0 Fix `elided_named_lifetimes` in code f49a44cf1e2 Improve documentation for ::from_str_radix 5199ea6314a Move remove_dir_all impl into a module 98acfd86719 Rollup merge of #129754 - alexcrichton:fix-wasi-long-sleep, r=workingjubilee 4050c9c6672 Rollup merge of #129675 - lolbinarycat:bufreader_peek_unsized, r=workingjubilee 7b7e734d010 Rollup merge of #129642 - workingjubilee:bump-backtrace-fc37b22, r=workingjubilee f7e36e58876 Rollup merge of #129640 - saethlin:unignore-android-in-alloc, r=tgross35 489dd6ea947 Fixed more typos in library/core df383f88d84 Fixed typos in btree map docs 28d3830c595 Fixed some typos in the standard library documentation/comments 04b539656d8 enumerate the two parts of the NaN rules da8d00e763f add hyphen in floating-point 30e703b7036 Squashed `aarch64_unknown_nto_qnx700` support b41accea14f Merge from rustc f14b6c62c3b add new_cyclic_in for Arc 24958a11fe5 improve comments fc7c3f25d89 fix new_cyclic_in for rc f296540064f fix fmt 42e304fcfe7 Try latest backtrace 2f2d0cae656 wasi: Fix sleeping for `Duration::MAX` f6a98d7a376 Rollup merge of #128166 - ChaiTRex:isqrt, r=tgross35 198003d5c4d Rollup merge of #123940 - kornelski:remove-derived-debug, r=Urgau df35fbd98e3 Box validity: update for new zero-sized rules 39cf25ecc0b Use simpler branchy swap logic in tiny merge sort 1a7869d462b f32 docs: define 'arithmetic' operations 40858b8540f Merge from rustc c14f27cec06 Speed up `checked_isqrt` and `isqrt` methods 3868b6905c0 Improve `isqrt` tests and add benchmarks 62bc0288df9 Rollup merge of #129715 - Amjad50:update-compiler-builtins, r=tgross35 07e211fb398 Rollup merge of #129683 - RalfJung:copysign, r=thomcc 124c0247c39 Rollup merge of #129673 - matthewpipie:arc-weak-debug-trait, r=dtolnay c00c0fd0d76 Rollup merge of #129401 - workingjubilee:partial-initialization-of-stabilization, r=dtolnay,joboet 0b0b89d42e7 Rollup merge of #129378 - goffrie:patch-3, r=ChrisDenton 6a4eb21ec6d Rollup merge of #128192 - mrkajetanp:feature-detect, r=Amanieu caf3c9676a6 add guarantee about remove_dir and remove_file error kinds ea21784d66f Update `compiler_builtins` to `0.1.123` 66fd0026dc0 fmt-debug option 0bbec8d942d allow BufReader::peek to be called on unsized types 2582cf5211e Auto merge of #129691 - matthiaskrgr:rollup-owlcr3m, r=matthiaskrgr 9e01d802e9f Rollup merge of #129668 - coolreader18:fix-pin-set-regr, r=dtolnay 47666a6796d Rollup merge of #129657 - jswrenn:transmute-name, r=compiler-errors 139a16f5a9e Rollup merge of #129551 - RalfJung:ub-checks-fallback, r=saethlin 5f50e4256ca Rollup merge of #129480 - lolbinarycat:euclid-docs, r=joboet 9e3a942b03f Enable some ilog2 tests as well ba56e21a573 Re-enable android tests/benches in alloc 29e15a82be7 Auto merge of #129589 - saethlin:improve-panic-immediate-abort, r=tgross35 c1b457a01bf copysign with sign being a NaN is non-portable 3fef81ba68f addr_of on places derived from raw pointers should preserve permissions 7e52cf8d173 add new_cyclic_in for rc e92e8ccec2d Add fmt::Debug to sync::Weak 1b4c972b6db Fix Pin::set bounds regression 7846bf3f472 library: Stabilize new_uninit for Box, Rc, and Arc 5207a611ef5 Rollup merge of #129652 - RalfJung:ptr-to-ref, r=traviscross 127b951085d Rollup merge of #129645 - beetrees:fix-float-docs, r=tgross35 9212a7df595 Rollup merge of #129581 - RalfJung:exit, r=joshtriplett b903869c425 safe transmute: Rename `BikeshedIntrinsicFrom` to `TransmuteFrom` 74e856d7e2c Auto merge of #128134 - joboet:move_pal_alloc, r=cupiver 17d26239dcc fix Pointer to reference conversion docs aebce516eb5 clarify that addr_of creates read-only pointers ad76dbb548d rustc_target: Add SME aarch64 features db895dacbfa rustc_target: Add various aarch64 features 83ca623feee std: move allocators to `sys` 3b874c8171d Use last swap optimization in bubblesort 24ae95178e5 Don't skip nonexistent source files d0482cef40a Add `cargo::rerun-if-changed` directives for source directories 87d0e01ed3a Always include `WindowsMMap.c` in the list of source files aacf68a1fa9 Sort the list of source files dc11f331ed7 Remove `InstrProfilingBiasVar.c` from the list of source files c4b58ed7832 Use helper functions to read environment variables 404ab839df2 Rollup merge of #129559 - RalfJung:float-nan-semantics, r=thomcc 8935e650e1d Rollup merge of #128731 - RalfJung:simd-shuffle-vector, r=workingjubilee f56ec4e851f Update old comment referring to `libcompiler_builtins` 134865feb57 Reflow a couple of paragraphs in floating-point primitive docs 93717835100 Fix typos in floating-point primitive type docs 2990feba855 Bump backtrace to rust-lang/backtrace@fc37b22 43dc357676b Rollup merge of #129032 - jswrenn:transmute-method, r=compiler-errors ae110687d8d Rollup merge of #128157 - lolbinarycat:unify-ptr-ref-docs, r=cuviper 8d076f45a19 Apply suggestions from code review b41c6029bae Rollup merge of #129592 - saethlin:core-cfg-test, r=tgross35 42e260abf79 Rollup merge of #129588 - hermit-os:sleep-micros, r=workingjubilee b44b20fd2a9 Rollup merge of #129539 - oconnor663:poll_link, r=tgross35 e9682b3ee99 Rollup merge of #129377 - chorman0773:unbounded-shifts-impl, r=scottmcm 66a00ad92c1 also update copysign docs 49fd0deb9e7 move per-target NaN info into a table 64d1626fac5 float types: document NaN bit pattern guarantees 7be29f6de40 Convert cfg blocks to cfg_if 02fb6dfeb11 Reduce code duplication by moving partition_lomuto_branchless_simple into quicksort module 02b21fa559c Auto merge of #129595 - matthiaskrgr:rollup-4udn7nn, r=matthiaskrgr aabba670efa Remove cfg(test) from library/core 407666401ed Rollup merge of #129544 - mu001999-contrib:dead-code/clean, r=compiler-errors d926d1a03b3 Rollup merge of #129525 - notriddle:notriddle/fake-variadic-tuple-array, r=GuillaumeGomez ff577cf1499 Auto merge of #129488 - saethlin:alignment-precondition, r=workingjubilee 2b99e5bdda8 pal/hermit: saturate `usleep` microseconds at `u64::MAX` 05d8b9aa7c0 Auto merge of #129563 - matthiaskrgr:rollup-t6bai2d, r=matthiaskrgr e81bf0901c5 Tweak some attributes to improve panic_immediate_abort 3bd9f572f9f pal/hermit: correctly round up microseconds in `Thread::sleep` e89bbb16ee0 Add binary-size optimized variants for stable and unstable sort as well as select_nth_unstable ebeac183240 exit: explain our expectations for the exit handlers registered in a Rust program 4e561829384 link to Future::poll from the Poll docs 53da3857b07 Rollup merge of #129487 - GrigorenkoPV:repr_transparent_external_private_fields, r=compiler-errors f04c3a07c78 Rollup merge of #129416 - workingjubilee:partial-move-from-stabilization, r=dtolnay 9bd53839a1d Rollup merge of #129091 - RalfJung:box_as_ptr, r=Amanieu 4d9ad0e9a84 Auto merge of #129295 - Zalathar:profiler-builtins, r=Kobzol ff1d4e68b76 ub_checks intrinsics: fall back to cfg(ub_checks) 139f2272b9e Auto merge of #129521 - matthiaskrgr:rollup-uigv77m, r=matthiaskrgr a5e4341ae97 Removes dead code from the compiler 5077ddbbc5e Rollup merge of #129481 - scottmcm:update-cb, r=tgross35 22b58a42513 Rollup merge of #129449 - coolreader18:pin-as_deref_mut-signature, r=dtolnay 58a6d3e71f3 Rollup merge of #128735 - jieyouxu:pr-120176-revive, r=cjgillot 4dc0e8c6bc4 rustdoc: clean up tuple <-> primitive conversion docs 48804a7f099 Rollup merge of #129501 - RalfJung:miri-rust-backtrace, r=Noratrieb 42c44e81328 Rollup merge of #129500 - fee1-dead-contrib:fxrel, r=compiler-errors 6780a99ff48 Rollup merge of #129323 - Urgau:ptr_fn_addr_eq, r=Mark-Simulacrum 9a14a84949f Rollup merge of #128596 - RalfJung:const_fn_floating_point_arithmetic, r=nnethercote 94662a15816 New `#[rustc_pub_transparent]` attribute 16315f2ad6c panicking: improve hint for Miri's RUST_BACKTRACE behavior 7327b627d84 Build `library/profiler_builtins` from `ci-llvm` if appropriate 88f425ebd75 remove invalid `TyCompat` relation for effects 0c66b50536d library: Move unstable API of new_uninit to new features 997b6132102 Pass `fmt::Arguments` by reference to `PanicInfo` and `PanicMessage` 89cf164ac46 Enable Alignment::new_unchecked precondition check 532d776d434 Change `f16` doctests in core to run on x86-64 linux 8209ca51a46 Update `compiler_builtins` to `0.1.121` 1883babc6f3 Enable `f16` tests on x86 and x86-64 ad0904c51f7 docs: correct panic conditions for rem_euclid and similar functions 562ffa48c8c Move into_inner_unchecked back to the bottom of the impl block 66fdeb9d8bf Put Pin::as_deref_mut in impl Pin 924c62a3cc6 document & impl the transmutation modeled by `BikeshedIntrinsicFrom` eb0c5ce42ac Auto merge of #129464 - GuillaumeGomez:rollup-ckfqd7h, r=GuillaumeGomez 47a97ad9ef2 Rollup merge of #129276 - eduardosm:stabilize-char_indices_offset, r=Amanieu e4d0a2d9b41 Rollup merge of #129400 - Amjad50:update-compiler-builtins, r=tgross35 6142f618402 Rollup merge of #127623 - lolbinarycat:fix_remove_dir_all, r=Amanieu 1570b347c44 Implement feature `string_from_utf8_lossy_owned` c2ee533d229 Check that `library/profiler_builtins` actually found some source files eda3042836a fix typos in new pointer conversion docs 641126d03b3 fix: fs::remove_dir_all: treat ENOENT as success c19e23cf9ec Update chown help with a link and adding cap warning b4f89a2ffd5 Expand std::os::unix::fs::chown() doc with a warning 2d206ec3806 feat(core): Make `unbounded_shl{l,r}` unstably const and remove `rustc_allow_const_fn_unstable` 7b717a0d89a Auto merge of #129398 - matthiaskrgr:rollup-50l01ry, r=matthiaskrgr 16b734b574f Update `compiler_builtins` to `0.1.120` 22cc20b5dc5 stabilize const_fn_floating_point_arithmetic 274455997f7 Rollup merge of #129382 - tgross35:once-cell-const-into-inner, r=Noratrieb c3f7d2d7280 Rollup merge of #129376 - ChaiTRex:assert_unsafe_precondition_check_language_ub, r=workingjubilee,the8472 e3d8fb2f33f Rollup merge of #129374 - ChaiTRex:digit_unchecked_assert_unsafe_precondition, r=scottmcm 8ec7ffe2818 Rollup merge of #128432 - g0djan:godjan/wasi_prohibit_implicit_unsafe, r=tgross35 69dab00d203 Auto merge of #129365 - matthiaskrgr:rollup-ebwx6ya, r=matthiaskrgr 6b592afe231 fix(core): Use correct operations/values in `unbounded_shr` doctests 86e7eed6a37 chore: `x fmt` ce221f85d5c fix(core): Add `#![feature(unbounded_shifts)]` to doctests for `unbounded_shr`/`unbounded_shl` 39d2f37be4f Add `const_cell_into_inner` to `OnceCell` b0f1117e4f9 format 110584a61c8 chore: `x fmt` and hopefully fix the tidy issue 048c37079b5 Clean up cfg-gating of ProcessPrng extern 04ba3592c8c Change `assert_unsafe_precondition` docs to refer to `check_language_ub` ff54653cf40 chore: Also format the control flow 9738b7b85c7 Manually format functions and use `rhs` instead of `v` from my CE testing b949515eb2a feat(core): Add implementations for `unbounded_shl`/`unbounded_shr` 7cb313c265b Use `assert_unsafe_precondition!` in `AsciiChar::digit_unchecked` 867ca6734f7 Rollup merge of #129321 - krtab:float_sum, r=workingjubilee 894d4a1c478 Rollup merge of #129232 - ivmarkov:master, r=workingjubilee 298a4401240 Rollup merge of #127945 - tgross35:debug-more-non-exhaustive, r=Noratrieb 1f9eed1e6ff Rollup merge of #129332 - cuviper:cstr-cast, r=compiler-errors b2998a79479 Rollup merge of #129312 - tbu-:pr_str_not_impl_error, r=Noratrieb 44916d9291b Fix stability attribute of `impl !Error for &str` e92fd5a6d80 Auto merge of #126556 - saethlin:layout-precondition, r=joboet 420de9b062a Auto merge of #128866 - scottmcm:update-stdarch, r=tgross35 0ee4fad835d Update stdarch submodule 8bb4defbbc0 Try to golf down the amount of code in Layout bdaea0a64e0 Avoid extra `cast()`s after `CStr::as_ptr()` 05f74bc93e8 Rollup merge of #129294 - scottmcm:stabilize-repeat-n, r=Noratrieb 83912958c72 Implement `ptr::fn_addr_eq` ccb4d7e8ae4 Change neutral element of to neg_zero a301d25f87e Stabilize `iter::repeat_n` 8ef5ba75d38 Auto merge of #129226 - RalfJung:libc, r=Mark-Simulacrum 6098afcc076 Add a precondition check for Layout::from_size_align_unchecked f3f2cdb236c Stabilize feature `char_indices_offset` 05add7e0607 docs: Mention `spare_capacity_mut()` in `Vec::set_len` 295b8060111 library: bump libc dependency d791785016e Rollup merge of #128902 - evanj:evan.jones/env-var-doc, r=workingjubilee 9aad6187d39 Document futility of printing temporary pointers 8c56f4c6221 soft-deprecate the addr_of macros c7450a32a43 code review improvements cd135c0017b Fix for issue #129212 for the ESP-IDF b3ed40c7c23 Auto merge of #126877 - GrigorenkoPV:clone_to_uninit, r=dtolnay 2ae826feda2 Auto merge of #128598 - RalfJung:float-comments, r=workingjubilee 239cf661fc1 Auto merge of #106943 - mina86:exact_size_take_repeat, r=dtolnay 336b7b87ba8 Auto merge of #116528 - daxpedda:stabilize-ready-into-inner, r=dtolnay 370fb550262 Rollup merge of #129161 - dtolnay:spawnunck, r=Noratrieb 29ce4a765e4 Rollup merge of #129086 - slanterns:is_none_or, r=dtolnay d4ce961f36b Stabilize std::thread::Builder::spawn_unchecked f71fbc6b4a0 Refer to other docs cbd6a2d8029 float to/from bits and classify: update comments regarding non-conformant hardware 1e67aebba81 Rollup merge of #128064 - ijackson:noop-waker-doc, r=workingjubilee ed38b932739 Add cautionary paragraph about noop wakers. 0b8ea218c97 Add unordered list with possible values for each const d8e7fb27601 Format std::env::consts docstrings 3739a26df2d Rollup merge of #128946 - orlp:faster-ip-hash, r=joboet 393d80401f2 Rollup merge of #128925 - dingxiangfei2009:smart-ptr-helper-attr, r=compiler-errors 4a2464dfd97 Rollup merge of #125970 - RalfJung:before_exec, r=m-ou-se f77b0b1e677 size-optimize some of the panic dependencies fe4e64ac86e apply #[optimize(size)] to #[cold] ones and part of the panick machinery 5c236f0bce3 Rollup merge of #128954 - zachs18:fromresidual-no-default, r=scottmcm 27c24a22f01 Rollup merge of #128570 - folkertdev:stabilize-asm-const, r=Amanieu 6b9bff59558 add Box::as_ptr and Box::as_mut_ptr methods fdca77bd5cf CommandExt::before_exec: deprecate safety in edition 2024 50e27bccd40 stabilize `option_get_or_insert_default` 8c33ec88485 stabilize `is_none_or` 6449aa48875 Auto merge of #129060 - matthiaskrgr:rollup-s72gpif, r=matthiaskrgr 0654b304088 Rollup merge of #129001 - cblh:fix/128713, r=Noratrieb e6a866af724 Rollup merge of #128873 - ChrisDenton:windows-targets, r=Mark-Simulacrum dc2766507ee Rollup merge of #128759 - notriddle:notriddle/spec-to-string, r=workingjubilee,compiler-errors 17b84a7a5d2 Make `std::os::darwin` public 074171f9a8e stabilize `asm_const` 385f9ea8a9a Rollup merge of #129034 - henryksloan:coroutine-must-use, r=joboet c47ed0e67de Rollup merge of #127857 - tbu-:pr_deprecated_safe_todo, r=petrochenkov 2ba61bc9ae1 Rollup merge of #122884 - mzabaluev:pow-remove-exit-branch, r=Amanieu 9792d2e746a Reduce merged doctest source code size 16ebfcab7a5 Mark location doctest as standalone since file information will not work in merged doctest file 71571b1ab92 Auto merge of #129046 - matthiaskrgr:rollup-9x4xgak, r=matthiaskrgr 7e629671a64 Rollup merge of #128745 - dtolnay:spawnunchecked, r=workingjubilee a0f2969aaf5 Rollup merge of #128655 - joboet:play_with_the_dice, r=ChrisDenton fb739ad3e32 `#[deprecated_safe_2024]`: Also use the `// TODO:` hint in the compiler error 6197509cac5 Allow to customize `// TODO:` comment for deprecated safe autofix 041effa142b Auto merge of #128962 - devnexen:fs_get_mode_haiku, r=workingjubilee 654cd8a23d2 simd_shuffle intrinsic: allow argument to be passed as vector (not just as array) d186e550539 Revert to original loop for const pow exponents e4ad3d26a5a Auto merge of #128742 - RalfJung:miri-vtable-uniqueness, r=saethlin 6d8812866ca Add must_use attribute to Coroutine trait d1e1878fa17 chore(lib): fmt core::fmt::Formatter's write_fmt method 001f7905b1b trying common codepath for every unixes 68ae5f13e1b std::fs: get_mode implementation for haiku. 0a2aa498bd4 Rollup merge of #129017 - its-the-shrimp:core_fmt_from_fn, r=Noratrieb 03d0b13b91e derive(SmartPointer): register helper attributes 279470e3a0c Explicitly specify type parameter on FromResidual impls in stdlib. 73df7c8e89b std::fmt::FormatterFn -> std::fmt::FromFn 90c97e6216e Rollup merge of #128632 - joboet:dont_overwrite_style, r=Amanieu fa421850fa5 Rollup merge of #128149 - RalfJung:nontemporal_store, r=jieyouxu,Amanieu,Jubilee a09f2578a37 chore(lib): Enhance documentation for core::fmt::Formatter's write_fmt method c0e45ea3af8 ignore some vtable/fn ptr equality tests in Miri, their result is not fully predictable 29366c3629d std: use `/scheme/rand` on Redox f052a93ff6f core: make documentation clearer, rename slice comparison specialization trait 491ed5ff87e std: do not overwrite style in `get_backtrace_style` 985e389bc68 Auto merge of #128862 - cblh:fix/128855, r=scottmcm c4d6ae2e139 Auto merge of #126793 - saethlin:mono-rawvec, r=scottmcm b4f222267bc Do not use unnecessary endian conversion. 7944666e30f Rollup merge of #128882 - RalfJung:local-waker-will-wake, r=cuviper 80d32588223 Rollup merge of #120314 - mina86:i, r=Mark-Simulacrum 5a1e51a5e7b Fix stability annotation and expand comment d83ddd3c10a Hash Ipv*Addr as an integer afac0791bab Auto merge of #128927 - GuillaumeGomez:rollup-ei2lr0f, r=GuillaumeGomez 90c9f07a6e6 Rollup merge of #128273 - Voultapher:improve-ord-violation-help, r=workingjubilee 2be6b1a708f Update std and compiler 3d3d49f3369 Stabilize `min_exhaustive_patterns` f9cae030b56 Add an optimizer hint for the capacity that with_capacity_in returns 910efd1221d Hoist IS_ZST check out of RawVecInner::from_*_in 9a1a6b15cd2 Polymorphize RawVec ac9a650584c core: optimise Debug impl for ascii::Char 5080e8e6f6a doc: std::env::var: Returns None for names with '=' or NUL byte 791430f1a8d Rollup merge of #128859 - MinxuanZ:mips-sig, r=Amanieu e3d6eacc6c6 Rollup merge of #128817 - biabbas:vxworks_update, r=tgross35 5674577de09 make LocalWaker::will_wake consistent with Waker::will_wake b192ee58803 Fix linkchecker issue 33c34c6f36d Exclude windows-targets from the workspace 3722bf3fa55 Add windows-targets crate to std's sysroot b3ad9d4751d Rollup merge of #128824 - GuillaumeGomez:update-compiler-builtins, r=Amanieu 67a4c614b70 VxWorks: Add safety comment for vxCpuEnabledGet 5b9da517f6f fix: Ensure `Guard`'s `drop` method is removed at `opt-level=s` for `Copy` types e43d6825563 delete space 64d490747dd fix format c5a6187489c [SPARC] fix the name of signal 19 in sparc arch 18fbbc5f15d [MIPS] fix the name of signal 19 in mips 2a896975db7 Rollup merge of #128818 - RalfJung:std-miri-floats, r=tgross35 4f2a2fb387c Rollup merge of #128640 - RalfJung:rwlock-macos-miri, r=joboet 8f129589836 Rollup merge of #128749 - tgross35:float-inline, r=scottmcm ee1a68039b2 Rollup merge of #128306 - WiktorPrzetacznik:WiktorPrzetacznik-nonnull-alignoffset-update, r=Amanieu af7fc3705b3 Update compiler-builtins version to 0.1.118 dfd72fe2f72 std float tests: special-case Miri in feature detection 9a5ce5ec1a3 Vxworks: Extern taskNameSet and fix build errors 0ea5511b9f4 rwlock: disable 'frob' test in Miri on macOS 6450f09c0a5 Fix VxWorks available parallelism: Move nonzero::uncheked into unsafe block 0cd655d22b1 Rollup merge of #128800 - clarfonthey:core-pattern-type, r=compiler-errors 879ac704ec2 Rollup merge of #128691 - tgross35:update-builtins, r=Amanieu 088244d9149 Add tracking issue to core-pattern-type 00d35782a19 Stabilize `Ready::into_inner()` 17d941e78c6 Rollup merge of #128261 - clarfonthey:iter-default, r=dtolnay d114d059c58 alloc: make `to_string_str!` a bit less complex ff4afe367ef Mark `{f32,f64}::{next_up,next_down,midpoint}` inline 67d116b27b8 Rollup merge of #128766 - Monadic-Cat:patch-1, r=tgross35 9956e8e2857 Rollup merge of #128417 - tgross35:f16-f128-math, r=dtolnay 4a514279e37 Trivial grammar fix in const keyword docs 1b22f5ab5df Update `compiler-builtins` to 0.1.117 aa0b5ee1f5d Rollup merge of #128751 - devnexen:vxworks_set_thread_name, r=tgross35 e26fdafbc48 Rollup merge of #128539 - biabbas:deny_unsafe, r=workingjubilee a1a64faf55f Rollup merge of #128406 - lolbinarycat:bufreader_peek, r=Mark-Simulacrum 26215cd522a Rollup merge of #125048 - dingxiangfei2009:stable-deref, r=amanieu 0efd7ed0210 alloc: add ToString specialization for `&&str` 513681a9bb2 std::thread: set_name implementation proposal for vxWorks. 05782ead8bc Remove unused lifetime parameter from spawn_unchecked d1f235c4663 Add a special case for CStr/CString in the improper_ctypes lint 5956c149d9a implement BufReader::peek ef578014b4d custom MIR: add support for tail calls b509ffc7883 nontemporal_store: make sure that the intrinsic is truly just a hint ade3a2a9376 WASI fixing unsafe_op_in_unsafe_fn for std::{os, sys} 5f4c167acbf Auto merge of #128673 - matthiaskrgr:rollup-gtvpkm7, r=matthiaskrgr 5430fccb83b Rollup merge of #128619 - glandium:last_chunk, r=scottmcm caef9415b11 Rollup merge of #128609 - swenson:smaller-faster-dragon, r=Amanieu c6ee8d7a15c Rollup merge of #128026 - devnexen:available_parallelism_vxworks, r=Mark-Simulacrum c1ef5d16b93 Rollup merge of #128309 - kmicklas:btreeset-cursor, r=Amanieu 3382ff2ffd2 Correct the const stabilization of `<[T]>::last_chunk` 21eca846cf9 Auto merge of #128534 - bjorn3:split_stdlib_workspace, r=Mark-Simulacrum e4251330abf std: refactor UNIX random data generation 4d4b0619580 refactor: standardize duplicate processes in parser 54f6dcbc433 Rollup merge of #128526 - tshepang:patch-1, r=Amanieu fb72790f22e Auto merge of #128466 - sayantn:stdarch-update, r=tgross35 e658a3bed09 Update stdarch 69746ed8c84 Chore: add `x86_amx_intrinsics` feature flag to `core/lib.rs` and remove `issue-120720-reduce-nan.rs` 668aab776c9 Rollup merge of #128551 - Konippi:refactor-backtrace-style-in-panic, r=tgross35 17f1aa06561 Rollup merge of #128530 - scottmcm:repeat-n-unchecked, r=joboet 4dfe7f2be3d Remove unnecessary constants from flt2dec dragon d0e321ac326 Apply review comments to PartialOrd section 2339e96fd99 Auto merge of #128404 - compiler-errors:revert-dead-code-changes, r=pnkfelix d8610a63bc7 Suppress new false-negatives that were masked by dead code analysis changes 5c38f9f37e2 Revert "Rollup merge of #127107 - mu001999-contrib:dead/enhance-2, r=pnkfelix" 1a6af6cb16d Rollup merge of #128368 - nnethercote:rustfmt-tweaks, r=cuviper 5abf6e003ec Rollup merge of #128303 - NobodyXu:specialise-for-pipe, r=cuviper ea998e2cb9b Rollup merge of #127586 - zachs18:more-must-use, r=cuviper 99177eb1e3d Rollup merge of #126704 - sayantn:sha, r=Amanieu 8233f4f6e37 Forbid unsafe_op_in_unsafe_fn in vxworks specific os and sys files 50622553c82 chore: refactor backtrace style in panic cf59be5ef67 Auto merge of #128528 - workingjubilee:you-dont-need-to-see-this-cpuid-move-along, r=Amanieu e1a12779774 Move the standard library to a separate workspace 48fb16da7d7 Auto merge of #128254 - Amanieu:orig-binary-search, r=tgross35 16e7aa3b1fd Implement `UncheckedIterator` directly for `RepeatN` d5a11bcfb83 Rollup merge of #128491 - c410-f3r:unlock-rfc-2011, r=workingjubilee 4c75deb8b81 Rollup merge of #128453 - RalfJung:raw_eq, r=saethlin 5153b0cbb97 std: Remove has_cpuid 14ab24db45b time.rs: remove "Basic usage text" 6ca8b4b08f0 Dogfood 51bfb6c0304 Add the `sha512`, `sm3` and `sm4` target features c1cdfea9361 Fix mutability in doc tests for `BTreeSet` cursors bb416156401 Add a disclaimer about x86 `f128` math functions 5f2c7d59060 Update comments for `{f16, f32, f64, f128}::midpoint` ecb0778cd65 Add `core` functions for `f16` and `f128` that require math routines ffbea3991e7 Add math functions for `f16` and `f128` 315a7b82378 Add math intrinsics for `f16` and `f128` 43242063608 Introduce `Cursor`/`CursorMut`/`CursorMutKey` thrichotomy for `BTreeSet` like map API 82a8f8e1b63 Fix some uses of "map" instead of "set" in `BTreeSet` cursor API docs a37b4d84fef Share `UnorderedKeyError` with `BTReeMap` for set API 879f7609d23 Rollup merge of #128499 - Konippi:refactor-backtrace-formatting, r=tgross35 f3cab6ff7e6 Rollup merge of #128497 - Bryanskiy:fix-dropck-doc, r=lcnr 78481f97c31 Rollup merge of #128433 - hermit-os:hermit-unsafe_op_in_unsafe_fn, r=joboet 098e12399ad Hide internal sort module 5d2482f42e3 chore: refactor backtrace formatting 6ac33536e0f fix dropck documentation for `[T;0]` special-case 7fd9be67a24 core: use `compare_bytes` for more slice element types 4861c3f6957 fix(os/hermit): `deny(unsafe_op_in_unsafe_fn)` 988691f1f73 fix(pal/hermit): `deny(unsafe_op_in_unsafe_fn)` 9b9e0001bdc refactor(pal/hermit): make `ENV` a non-mutable static ee5bd41eb9a Rollup merge of #128416 - maurer:remove-android-hack, r=tgross35 064635074f0 Auto merge of #128461 - matthiaskrgr:rollup-3dpp11g, r=matthiaskrgr 4251bcab60d Rollup merge of #128162 - ChrisDenton:cleanup, r=joboet 833165c11ad Rollup merge of #127567 - joboet:once_wait, r=Amanieu 6db50f12c86 Fix docs for OnceLock::get_mut_or_init c6676cf4135 raw_eq: using it on bytes with provenance is not UB (outside const-eval) 84a6d8ae33b std: fix busy-waiting in `Once::wait_force`, add more tests 9acfb0aaed6 std: implement the `once_wait` feature 41c563bbc9b Remove unneeded `pub(crate)` 339328989d0 Rollup merge of #128388 - beetrees:f16-f128-slightly-improve-windows-abi, r=tgross35 f7b6e4364ca Rollup merge of #128387 - liigo:patch-14, r=tgross35 bce6b74ea43 refactor(pal/hermit): use default impl of `GlobalAlloc::alloc_zeroed` 8b00cc57f0d refactor(pal/hermit): return `!` to satisfy rust-analyzer bd14a0d3dfa Apply review comments 8b6ef804cfb PinCoerceUnsized trait into core e91f4538dd7 android: Remove libstd hacks for unsupported Android APIs ce9539dd61e Move Windows implementation of anon pipe c1d778c0260 Match LLVM ABI in `extern "C"` functions for `f128` on Windows 3f17d07bd0c Cleanup sys module to match house style c0d2c473404 Auto merge of #128083 - Mark-Simulacrum:bump-bootstrap, r=albertlarsan68 5a2e821b39b Rewrite binary search implementation 597c7692614 More detailed note to deprecate ONCE_INIT e87699832c4 Auto merge of #128378 - matthiaskrgr:rollup-i3qz9uo, r=matthiaskrgr d84bde44378 Auto merge of #128250 - Amanieu:select_unpredictable, r=nikic ffbc0f59c25 Rollup merge of #128315 - zetanumbers:psvita-unsafe-in-unsafe, r=workingjubilee 94a8b5871de Auto merge of #128234 - jcsp:retain-empty-case, r=tgross35 fd9228fff5c Insert some blank lines. 79919da0630 Move a comment. 5532713d1a3 CloneToUninit: use a private specialization trait 423d1637d1a Sparkle some attributes over `CloneToUninit` stuff 695e2861d86 impl CloneToUninit for Path and OsStr aa1a60a2a5d impl CloneToUninit for str and CStr 21d7e3ddf8b Stabilize offset_of_nested 760b8a4bdca Auto merge of #128334 - matthiaskrgr:rollup-nhxdt0c, r=matthiaskrgr 4978465a715 Rollup merge of #128333 - RalfJung:miri-sync, r=RalfJung 39ade55e8a4 Rollup merge of #128307 - ojeda:unescaped_backticks, r=GuillaumeGomez 91a21c5cf23 Optimize empty case in Vec::retain 306e3f5c78d Auto merge of #125016 - nicholasbishop:bishop-cb-112, r=tgross35 5043f5b5645 Rollup merge of #128310 - kmicklas:btree-map-peek-next-docs, r=tgross35 cfa837e6e71 Rollup merge of #128055 - workingjubilee:deny-unsafe-ops-in-sys-personality-dwarf-eh, r=Amanieu 15bdbe5aaee Rollup merge of #109174 - soerenmeier:cursor_fns, r=dtolnay f25847cbea5 Update compiler_builtins to 0.1.114 fb9b677c4a0 Warn on `rustdoc::unescaped_backticks` for `core/alloc/std/test/proc_macro` 47d06c66944 Remove spurious backticks detected by `rustdoc::unescaped_backticks` d6fe06253ac Reformat `use` declarations. 1b34e246a0c Replace `io::Cursor::{remaining_slice, is_empty}` with `io::Cursor::{split, split_mut}` 9b11f3c0158 Partially stabilize `io_error_more` b33156fc023 step cfg(bootstrap) 57e4de0919d Update CURRENT_RUSTC_VERSION 0c9c55ac6d2 Add forbid(unsafe_op_in_unsafe_fn) 0ea9a04d9ee Rollup merge of #128240 - mbrubeck:patch-3, r=joboet 6bc22290410 Rollup merge of #128228 - slanterns:const_waker, r=dtolnay,oli-obk 386ac7278bf Rollup merge of #128103 - folkertdev:unsigned-int-is-multiple-of, r=Amanieu 9ac161902c8 Rollup merge of #127765 - bitfield:fix_stdlib_doc_nits, r=dtolnay a24e0d125cd fix: psvita's std code 81f2a8943cd Force LLVM to use CMOV for binary search 8458f3b1a09 stabilize const_waker b8611482ab4 Add missing periods on `BTreeMap` cursor `peek_next` docs 03af1759aed Implement cursors for `BTreeSet` 1843c73c1e9 Update NonNull::align_offset quarantees d53dc68813e Enable `std::io::copy` specialisation for `std::pipe::{PipeReader, PipeWriter}` c1346005914 Rollup merge of #128282 - pitaj:nonzero_bitwise, r=workingjubilee ec44d3063d1 Rollup merge of #128279 - slanterns:is_sorted, r=dtolnay b0b766cb0e5 stabilize `is_sorted` f7450df63f3 bitwise and bytewise methods on `NonZero` 2b1a922566e Rollup merge of #128259 - sunshowers:msg-nosignal, r=Mark-Simulacrum c88cf0b4996 Rollup merge of #125897 - RalfJung:from-ref, r=Amanieu 3b3b5e55205 Improve panic sections for sort*, sort_unstable* and select_nth_unstable* 5dfd5672bc8 Improve panic message and surrounding documentation for Ord violations f9b9ccc2d8d Auto merge of #128255 - stepancheg:doc-shl, r=scottmcm 796fa30a244 Okay, I guess I have to give these a different feature name 7da83febc3b impl Default for collection iterators that don't already have it 7e81e7bcc08 Merge from rustc 5395834faec Auto merge of #127946 - tgross35:fmt-builders-set-result, r=cuviper 656d6642a3e [illumos/solaris] set MSG_NOSIGNAL while writing to sockets 8da0bb274bc Document int.checked_shl(BITS - 1) 2b0599c29a0 Rollup merge of #128235 - harryscholes:fix-iterator-filter-docs, r=tgross35 eb5e08f6612 Rollup merge of #124941 - Skgland:stabilize-const-int-from-str, r=dtolnay 13ee5533cee Add links from `assert_eq!` docs to `debug_assert_eq!`, etc. 8bab71645bf Always set `result` during `finish()` in debug builders c4125be51a9 Fix docs aaa0695d37e Auto merge of #128165 - saethlin:optimize-clone-shims, r=compiler-errors baff1e417a8 Fix doc nits bb51f8078cc Rollup merge of #128170 - saethlin:clone-fn, r=compiler-errors 9c21cddad60 Merge from rustc a6a33351cd1 Rollup merge of #128211 - juliusl:pr/align-change-time, r=tgross35 6586d771bcc Rollup merge of #128150 - BoxyUwU:std_only_sized_const_params, r=workingjubilee 92981cc1f68 Rollup merge of #127950 - nnethercote:rustfmt-skip-on-use-decls, r=cuviper 6187824881f Make Clone::clone a lang item 42e954a1a0a fix: compilation issue w/ refactored type 349f266ad8d Let InstCombine remove Clone shims inside Clone shims 0091c5d49cf Stop using `unsized_const_parameters` in core/std cc16d8b9820 Auto merge of #128195 - matthiaskrgr:rollup-195dfdf, r=matthiaskrgr 660c9ba28b9 Rollup merge of #128137 - GrigorenkoPV:cstr-derive, r=dtolnay 0555ad8403b Rollup merge of #127999 - ChrisDenton:arm32, r=Amanieu 37e03570d3f clarify interactions with MaybeUninit and UnsafeCell e90c3af2f97 remove duplicate explanations of the ptr to ref conversion rules a829e2e95cb create a new section on pointer to reference conversion 9cb55d3971b Rollup merge of #128158 - workingjubilee:unsafe-wrap-personality-gcc, r=ChrisDenton 5b9cb522e05 Rollup merge of #127300 - biabbas:fix_connect_timeout, r=tgross35 4c7b48e8c6d CStr: derive PartialEq, Eq; add test for Ord ffcd9ebc738 In connect timeout, read readiness of socket for vxworks. Check pollhup or pollerr for refused connections in linux 28bd85365d4 Merge from rustc ee43dcc74b9 Implement `mixed_integer_ops_unsigned_sub` 7c2450e9097 std: update comments on gcc personality fn 65f1a66013c std: unsafe-wrap gcc::rust_eh_personality and impl 3ad4bb8f716 Rollup merge of #128135 - joboet:reduplicate_tls, r=tgross35 f8cc4959ce2 Rollup merge of #128046 - GrigorenkoPV:90435, r=tgross35 349ab78b126 Rollup merge of #126548 - rik86189:issue-88264-fix, r=tgross35 a23ed32f0d8 Rollup merge of #126042 - davidzeng0:master, r=Amanieu 97fe8ba43c2 Rollup merge of #128131 - ChrisDenton:stuff, r=workingjubilee 039de34a827 Rollup merge of #128120 - compiler-errors:async-fn-name, r=oli-obk 5bed9b939cc Rollup merge of #127733 - GrigorenkoPV:don't-forget, r=Amanieu 17af9e1fa00 Rollup merge of #127480 - biabbas:vxworks, r=workingjubilee 37f7b8295df Rollup merge of #127252 - fitzgen:edge-cases-for-bitwise-operations, r=m-ou-se d1243fd7c2d Rollup merge of #126152 - RalfJung:size_of_val_raw, r=saethlin b5096447d4b Improved clarity of documentation for std::fs::create_dir_all 89f06d6efdf std: use duplicate thread local state in tests 7c7c9fd4129 Forbid unsafe_op_in_unsafe_fn in sys/pal/windows 583f4e47a88 Import `core::ffi::c_void` in more places f4498dfc79e Merge from rustc 1bc6a9b1ae1 Add chroot unsupported implementation for VxWorks e1359301fbf Rollup merge of #128106 - hallfox:patch-1, r=ChrisDenton c6df5d4f45d Rollup merge of #128092 - ChrisDenton:wrappers, r=workingjubilee b842b545a93 Rollup merge of #128043 - safinaskar:primitive, r=workingjubilee 4f87437ba50 Rollup merge of #127481 - a1phyr:pattern_gat, r=Amanieu 71682f78167 Rollup merge of #126770 - wr7:master, r=Amanieu f35a8d0d158 Rollup merge of #125962 - Coekjan:const-binary-heap, r=Amanieu a99f3b1b37a Auto merge of #127153 - NobodyXu:pipe, r=ChrisDenton 6ca8129d090 Gate AsyncFn* under async_closure feature 85ef9fb395a Add elem_offset and related methods 1da10d0b534 library/core/src/primitive.rs: small doc fix 72088e4b150 Fix return type of FileAttr methods on AIX target b2a89a7023e add `is_multiple_of` for unsigned integer types 611821889fb Initial implementation of anonymous_pipe 9d149af8f6f Update process vxworks, set default stack size of 256 Kib for vxworks. User can set the stack size using RUST_MIN_STACK, with min size of libc::PTHREAD_STACK_MIN(4kib) c239e5ed051 Rollup merge of #128089 - workingjubilee:commonly-wrapped-to-make-safe, r=ChrisDenton a3d665677c7 Rollup merge of #125834 - workingjubilee:weaken-thir-unsafeck-for-addr-of-static-mut, r=compiler-errors 621c304ff64 Remove wrapper functions from c.rs 5976bfbf2f0 std: Unsafe-wrap backtrace code held in-common 815ffaed8d1 std: Unsafe-wrap alloc code held in-common cea3bc9d58b Cfg disable on_broken_pipe_flag_used() for vxworks f269f5134ec Disable dirfd for vxworks, Return unsupported error from set_times and lchown for vxworks 7fbb01908f3 Allow unused unsafe for vxworks in read_at and write at b9074a3991f Docs for core::primitive: mention that "core" can be shadowed, too, so we should write "::core" e7435538c22 library: vary unsafety in bootstrapping for SEH f84c8b9e15b std: unsafe-wrap personality::dwarf::eh 27ef46334fc LocalWaker docs: Make long-ago omitted but probably intended changes f5cf0e7d131 Docs for Waker and LocalWaker: Add cross-refs in comment baaa8319bd9 Rollup merge of #128008 - weiznich:fix/121521, r=lcnr fe5a96c80e3 Rollup merge of #127996 - ian-h-chamberlain:fix/horizon-warnings-unsafe-in-unsafe, r=tgross35 cbf3c70aa99 Rollup merge of #127415 - AljoschaMeyer:master, r=dtolnay 276e3b8dbfe Use given allocator instad of Global 75b04c206d8 Start using `#[diagnostic::do_not_recommend]` in the standard library 8034f1e57d4 Rollup merge of #127583 - Nilstrieb:invalid-utf8, r=joboet f150fa00f3e Fix warnings when checking armv6k-nintendo-3ds 9a901baa759 Fix some `#[cfg_attr(not(doc), repr(..))]` c9d93fc4b70 Implement `debug_more_non_exhaustive` fef718940c7 Make use of raw strings in `core::fmt::builders` a30a757ccba Deal with invalid UTF-8 from `gai_strerror` 9b1dee5e060 std::thread: available_parallelism implementation for vxWorks proposal. 37e225f24a0 Auto merge of #127722 - BoxyUwU:new_adt_const_params_limitations, r=compiler-errors ee9c9fff3bb Rollup merge of #128005 - ChrisDenton:msvc-include, r=joboet 6ba9071f527 Rollup merge of #127734 - ChrisDenton:netc, r=Mark-Simulacrum f1a4f4ef3ac Remove _tls_used hack 31d7a8beff7 Rollup merge of #127873 - workingjubilee:forbid-unsafe-ops-for-kmc-solid, r=Amanieu 6da9e2995e8 Rollup merge of #127843 - workingjubilee:break-up-big-ass-stack-overflow-fn, r=joboet 3b549c075e7 Inject win arm32 shims into metadata generation b12e577f5fd Rollup merge of #127918 - ChrisDenton:thread-name-string, r=joboet 487201fe1cc Rollup merge of #123196 - Ayush1325:uefi-process, r=joboet 393c502acd6 std: forbid unwrapped unsafe in unsupported_backslash 0415d1480e6 kmc-solid: forbid(unsafe_op_in_unsafe_fn) 5b52717503a Auto merge of #127982 - matthiaskrgr:rollup-nzyvphj, r=matthiaskrgr 3d0a0c96628 Rollup merge of #127978 - nyurik:lib-refs, r=workingjubilee a4cfefebf85 Avoid ref when using format! for perf 165caf8a54a Rollup merge of #126199 - ivan-shrimp:nonzero_isqrt, r=tgross35 35de37e51e3 Rollup merge of #112328 - juliusl:pr/windows-add-change-time, r=ChrisDenton c01a76c49f6 uefi: process: Fixes from PR 791d351c3b7 uefi: process: Final Touchups b0c2adbadda uefi: process: Add CommandArgs support 7782dc83140 uefi: process: Add support for args 20e8df65e4f uefi: process Implement inherit e74d51830a3 uefi: process: Add null protocol 69840e609dd uefi: process: Add stderr support 55c11d68b84 uefi: process: Add support to capture stdout 19cd67745ed uefi: Add process bca10bff78b improve safety comment ae0cf774d59 add `NonZero::isqrt` d9a7ff5213c Use `#[rustfmt::skip]` on some `use` groups to prevent reordering. f3f4065b7ab unix: acquire-load NEED_ALTSTACK 22458b152bf unix: Unsafe-wrap stack_overflow::{drop,make}_handler 4a55e49db83 unix: Unsafe-wrap stack_overflow::cleanup 0eec22bf066 unix: lift init of sigaltstack before sigaction 6d917b400de unix: Unsafe-wrap stack_overflow::signal_handler 867b22b5766 Rollup merge of #127594 - c6c7:fuchsia-status-code-match-arm, r=tmandry f81f0b64add Move ThreadName conversions to &cstr/&str 3949036de01 Style change 09845ba8d7f Make `Thread::new_inner` a safe function dcf27e53f7f Rollup merge of #127748 - scottmcm:option_len, r=joboet 5c302b9b4e4 Rollup merge of #124881 - Sp00ph:reentrant_lock_tid, r=joboet d0b0fe22444 Update `ReentrantLock` implementation, add `CURRENT_ID` thread local. dbb45c0bb9f Safely enforce thread name requirements 73a7f0dda01 Rollup merge of #127077 - tbu-:pr_doc_fd_to_owned, r=workingjubilee 14717a37d6c Rollup merge of #127861 - Kriskras99:patch-1, r=tgross35 729197ef763 Rollup merge of #127859 - RalfJung:ptr-dyn-metadata, r=scottmcm eebad4c8275 Rollup merge of #127845 - workingjubilee:actually-break-up-big-ass-stack-overflow-fn, r=joboet a5f4b2838bb Auto merge of #127865 - matthiaskrgr:rollup-8m49dlg, r=matthiaskrgr 5fccbb08f66 feat: adding ext that returns change_time for Windows 2bdf2622b9a Auto merge of #125942 - timokroeger:windows-once-futex, r=ChrisDenton 199007098d7 Rollup merge of #127337 - celinval:intrinsics-fallback, r=oli-obk 39d777e80fd Mention how you can go from `BorrowedFd` to `OwnedFd` and back 5cdbba748ce Make language around `ToOwned` for `BorrowedFd` more precise 1f30372396f Document the column numbers for the dbg! macro 1521f765171 ptr::metadata: update comment on vtable_ptr work-around d1e86af88ba ptr::metadata: avoid references to extern types ed3e6575fb5 Split part of `adt_const_params` into `unsized_const_params` ded95de92e0 Forbid `!Sized` types and references f6c86f1418d Rollup merge of #127813 - ChrisDenton:win-futex, r=joboet 741d449ecc9 Rollup merge of #127763 - ChrisDenton:safe-unsafe-unsafe, r=tgross35 273e6f7d448 unix: unsafe-wrap install_main_guard_default ed063b6d13c unix: clean up install_main_guard_freebsd 1bbddab1bbe unix: stack_start_aligned is a safe fn 479002c918b unix: split stack_overflow::install_main_guard by os 9d693f2788d Prevent double reference in generic futex 2ac45f1092f Narrow the scope of the ReadFile unsafe block d0b650905ca forbid(unsafe_op_in_unsafe_fn) in sys/os_str 7a5f47a0df4 Rollup merge of #127836 - workingjubilee:forbid-unsafe-ops-in-xous-uefi, r=tgross35 1042c52fa2f Rollup merge of #127833 - risc0:erik/zkvm-deny-unsafe, r=workingjubilee 7bd7627298b Rollup merge of #127807 - ChrisDenton:win-parking, r=joboet 67b6d067259 Rollup merge of #127792 - workingjubilee:read-unaligned-is-dwarfier, r=joboet fa82c6a32be Rollup merge of #127444 - Sky9x:cstr-bytes-iter, r=dtolnay 045c2f84a79 Rollup merge of #126776 - nnethercote:rustfmt-use-pre-cleanups-2, r=cuviper 7fc4b5c4059 Rollup merge of #126271 - diondokter:dec2flt-skip-fast-path, r=tgross35 a7c630606e4 Rollup merge of #125206 - mgeisler:simplify-std-env-vars, r=jhpratt,tgross35 64df8bf38fc uefi: Forbid unwrapped unsafe in platform modules fb04b71cd57 Cfg nit 86486e6ee79 xous: Forbid unwrapped unsafe in platform modules 2cc0210ed43 zkvm: add `#[forbid(unsafe_op_in_unsafe_fn)]` in `stdlib` 8446953bb32 Adjust some comments on individual `use` declarations. 2f10b301656 Avoid comments that describe multiple `use` items. bf927d69277 Merge some `core::iter` entries. 45f9022aeee Add unsafe blocks in unsafe Thread::new 7428cac310d Remove `slice_to_end` eca53d8ab6a std: unwrapped unsafe is VERBOTEN! eb380a2501a Rollup merge of #127789 - Sword-Destiny:master, r=petrochenkov 39eaf475d08 Use futex.rs for Windows thread parking fc708d89c91 std: Use read_unaligned for reading DWARF dec0cb5a442 Rollup merge of #127047 - tspiteri:f128-aconsts-lsd, r=tgross35 35b8c2a9e6f deny unsafe_op_in_unsafe_fn for teeos 5d8a87e5b75 clean unsafe op in unsafe fn 9da88fb052a clean unsafe op in unsafe fn 7e8bbfdeda6 clean unsafe op in unsafe fn d228510adf1 delete #![allow(unsafe_op_in_unsafe_fn)] ae3b9d0c9af `impl Send + Sync` and override `count` for the `CStr::bytes` iterator 7c7397d731d Update name of Windows abort constant to match platform documentation 3c678cbfb4b Add match arm for Fuchsia status code upon an abort in a test 83c01446d98 Auto merge of #127777 - matthiaskrgr:rollup-qp2vkan, r=matthiaskrgr 7d7fb277638 Rollup merge of #124921 - RalfJung:offset-from-same-addr, r=oli-obk 4ee56d4d5bc lib: replace some `mem::forget`'s with `ManuallyDrop` 09075132e01 Auto merge of #127020 - tgross35:f16-f128-classify, r=workingjubilee cee987e8cf7 allow(unsafe_op_in_unsafe_fn) on some functions a7d4a8de6b3 Some Windows functions are safe 0d49922ec6c Deny more windows unsafe_op_in_unsafe_fn 6ffb056f152 Windows: move BSD socket shims to netc d994a556d65 Remove generic lifetime parameter of trait `Pattern` 598ecb15918 Rollup merge of #127750 - ChrisDenton:safe-unsafe-unsafe, r=workingjubilee 466f6d4f79b Rollup merge of #127744 - workingjubilee:deny-unsafe-op-in-std, r=jhpratt 130c1063824 Rollup merge of #127712 - ChrisDenton:raw-types, r=workingjubilee 3189577c18e Mark some `f16` and `f128` functions unstably const 45bf9e170e4 Use Option's discriminant as its size hint c0e0104ea98 Move safety comment outside unsafe block 87608069d2e Make os/windows default to deny unsafe in unsafe 4dcc733c933 Make pal/windows default to deny unsafe in unsafe 54751fa9525 Fix Windows 7 6074de59b92 Auto merge of #127719 - devnexen:math_log_fix_solill, r=Amanieu 8cdc886f321 Don't re-export `c_int` from `c` e3b1f78b10f Remove DWORD 98fb364dcdc Remove ULONG 560f6ed107e Remove PSRWLOCK 413a0b4176c Remove LPVOID 94aa5a82683 Remove LPSECURITY_ATTRIBUTES ee0da0e3745 Remove LPOVERLAPPED 16e929fe0f1 Remove LPCVOID c822637000a Remove SIZE_T 7faf18d15cf Remove CHAR 9163db9665f Remove USHORT 0b205be26c1 Remove LPWSTR 5b51933110f Remove UINT 11f77d1899e Remove LONG 0ac5c53fd9e Remove LARGE_INTEGER 79d89e2e08c Remove NonZeroDWORD 04ec57e847a Auto merge of #127732 - GrigorenkoPV:teeos-safe-sys-init, r=Amanieu 463206ff366 std: Unsafe-wrap std::sync 74b4f0372e0 std: Unsafe-wrap in Wtf8 impl 4d1cf416ce4 std: Unsafe-wrap std::io 7ae044eae21 std: Directly call unsafe {un,}setenv in env 1338eb67d1a std: Unsafe-wrap OSStr{,ing}::from_encoded_bytes_unchecked 58236456ca0 std: Unsafe-wrap HashMap::get_many_unchecked_mut 253847c15ca std: deny(unsafe_op_in_unsafe_fn) but allow sites 5019bfc9932 Add `classify` and related methods for `f16` and `f128` cbcef576601 std: removes logarithms family function edge cases handling for solaris. b06c8919b4a Auto merge of #127728 - matthiaskrgr:rollup-ercdbjd, r=matthiaskrgr 10970a16b9a sys::init is not unsafe on teeos 56f932059bd Rollup merge of #127592 - tesuji:patch-1, r=Mark-Simulacrum 1d744a4c448 Auto merge of #125935 - madsmtm:merge-os-apple, r=workingjubilee 1f1600f42f0 Merge Apple `std::os` extensions modules into `std::os::darwin` 4577f2082ac Rollup merge of #127704 - workingjubilee:fixup-better-than, r=ChrisDenton 5f6344b2809 Auto merge of #127706 - workingjubilee:rollup-d07ij30, r=workingjubilee 0960ce73397 Rollup merge of #127659 - saethlin:manually-drop-bufwriter, r=joboet 44be8a01076 Rollup merge of #127446 - zachs18:miri-stdlib-leaks-core-alloc, r=Mark-Simulacrum 6ac6fb4cce5 Rollup merge of #127370 - ChrisDenton:win-sys, r=Mark-Simulacrum 67e23981c01 doc: Suggest `str::repeat` over `iter::repeat().take().collect()` f313b55982a Fix minor typos in std::process doc on Win argv 9df9124ed1f Auto merge of #126958 - dtolnay:u32char, r=Mark-Simulacrum ffa66e331f0 std::unix::fs: removing, now useless, layers predating macOs 10.10. 46f805c45ac Auto merge of #127674 - jhpratt:rollup-0dxy3k7, r=jhpratt fb045375717 Rollup merge of #127668 - spencer3035:improve-slice-doc, r=jhpratt ac51b9c32c6 Rollup merge of #127661 - eduardosm:stabilize-io_slice_advance, r=cuviper 8999dfaef54 Auto merge of #127397 - jyn514:multi-thread-panic-hook, r=workingjubilee 5d63f37abad Auto merge of #126606 - zachs18:patch-2, r=joboet 460033c5ab8 Updated slice documentation b5ff5809bfd Use ManuallyDrop in BufWriter::into_parts 75d3633516f Use is_val_statically_known to optimize pow 8511bc33ca0 Stabilize io_slice_advance c968ee49a0d Rename the internal `const_strlen` to just `strlen` 27754cc3379 fix interleaved panic output f1770e22fc2 Rollup merge of #127433 - dtolnay:conststrlen, r=workingjubilee 60294fabcf0 Rollup merge of #126827 - the8472:pidfd-spawn, r=workingjubilee 475bb206612 Rollup merge of #124980 - zachs18:rc-allocator, r=Amanieu efd93b523dd Add instability attribute on private const_strlen function e8218cd6e5b Rollup merge of #127422 - greaka:master, r=workingjubilee ef5ce626879 [library/std/src/process.rs] `PartialEq` & `Eq` for `ExitCode` 0436f2572e0 Explicitly unroll integer pow for small exponents e7aa5864101 Optimize integer pow by removing exit branch f4ee51c78b0 Rollup merge of #127599 - tgross35:lazy_cell_consume-rename, r=workingjubilee 32268ea55c1 Rollup merge of #127588 - uweigand:s390x-f16-doctests, r=tgross35 95990132fda Rollup merge of #127572 - tbu-:pr_debug_event_nonpacked, r=jhpratt 7a6fc49a390 Rollup merge of #124599 - estebank:issue-41708, r=wesleywiser 4a506cdd93c Rename `lazy_cell_consume` to `lazy_cell_into_inner` e5ddddb3a6a Explicitly ignore `into_raw_handle()` using `let _ =` in sys/pal/windows. 816857e3ce8 core: Limit remaining f16 doctests to x86_64 linux 5523af99be4 Add `must_use` to IntoRawFd/IntoRawSocket/IntoRawHandle's methods. b776ed68a0b Clarify/add `must_use` messages for more `into_raw*` functions of `alloc` types. efe68779dc2 size_of_val_raw: for length 0 this is safe to call 5003488a4d9 Rollup merge of #127554 - ferrocene:tshepang-add-missing-attribute, r=pietroalbini d191b506a8e Don't mark `DEBUG_EVENT` struct as `repr(packed)` c297c30e71e Auto merge of #126690 - andyolivares:feature/show_window, r=dtolnay fab8206d8e7 Rollup merge of #127091 - Sky9x:fused-error-sources-iter, r=dtolnay 34511e79154 Fixed doc links cfaa231ff1a Few changes to doc comments. Added tracking issue number. cdbfbc4c346 Exposing STARTUPINFOW.wShowWindow in CommandExt (show_window function) to control how a new process should display its window (normal, minimized, maximized, etc) 2174c6993d0 do not run test where it cannot run 8ae8d7a446a Auto merge of #127235 - martn3:no-mips-f16, r=tgross35,scottmcm f18f28434a9 Rollup merge of #127460 - Borgerr:clarify-drop-comment, r=jhpratt 3dd18c0a49d Rollup merge of #127355 - aceArt-GmbH:126475, r=oli-obk 19d739e196c Rollup merge of #120248 - WaffleLapkin:bonk-ptr-object-casts, r=compiler-errors,oli-obk,lnicola 8d6985c41b3 Attempt to fix CI ecf3f1f043f Reset sigpipe not supported for vxworks 6a18048dd1b Rollup merge of #127367 - ChrisDenton:run-sync, r=Nilstrieb 3f9879edf6b Rollup merge of #126921 - workingjubilee:outline-va-list, r=Nilstrieb 3329af2365a Auto merge of #127454 - matthiaskrgr:rollup-k3vfen2, r=matthiaskrgr 0248b00c546 Move/change declaration of `mod exit_guard;` e896bf6eb5c clarify `sys::unix::fd::FileDesc::drop` comment (#66876) 58aab07fb57 Rollup merge of #127447 - RalfJung:once_lock_miri, r=joboet ec5b5ff7eb4 Rollup merge of #127354 - nicholasbishop:bishop-sized-doc, r=Nilstrieb dd6f93fa6bc Rollup merge of #127297 - the8472:path-new-hash, r=Nilstrieb 5277a5d1de8 Rollup merge of #127189 - GrigorenkoPV:linkedlist-cursor-list, r=Nilstrieb 1f3eba2fc32 Rollup merge of #127179 - tgross35:typeid-debug-hex, r=Nilstrieb cc82b6c4d26 once_lock: make test not take as long in Miri 1e00fd80c72 Remove non-focused memory leak in `std` doctest for Miri. 26e7afc99a7 Specialize `TrustedLen` for `Iterator::unzip()` dcd3f79cdd6 Mitigate focused memory leaks in `core` doctests for Miri. 660cb3dc81c Remove non-focused memory leaks in `core` doctests for Miri. 8a0bdf3e414 Mitigate focused memory leaks in `alloc` doctests for Miri. 316fb176871 Remove non-focused memory leaks in `alloc` doctests for Miri. 787a53e86c7 Stabilize const_cstr_from_ptr (CStr::from_ptr, CStr::count_bytes) 19546b49405 Fix them doc examples some more 4f88e8c1fa5 Fix doc examples c02028e3bc9 offset_from intrinsic: always allow pointers to point to the same address 98285d71f6f Run formatter on alloc/src/boxed.rs c7b37ac5194 Mark format! with must_use hint 345d65a3034 as_simd: fix comment to be in line with 507583a (#121201) b36f43410c2 Rollup merge of #127275 - RalfJung:offset-from-isize-min, r=Amanieu e52281fba2e Add missing try_new_uninit_slice_in and try_new_zeroed_slice_in 9010c109a8b Rollup merge of #125751 - pitaj:new_range_api, r=jhpratt 9bd07ddf5f7 Rollup merge of #127363 - GuillaumeGomez:improve-fmt-code-readability, r=Amanieu dee06aff668 Rollup merge of #127107 - mu001999-contrib:dead/enhance-2, r=pnkfelix afa796398c3 Rollup merge of #123600 - tisonkun:path_with_extension, r=dtolnay 388be53981f Attempt to fix CI 5188faa0ca5 add `new_range_api` for RFC 3550 fea9f55a7ec Move exit guard from sys::common::exit_guard to sys::exit_guard. c199dba1116 Update library/std/src/sys/pal/common/exit_guard.rs b6171bf4319 add unit tests for extra extension feature ff3961cf68a update comments 4f3a24a7e8a Add experimental raw-dylib feature to std 9650cb4edf3 Use windows_targets macro for alloc f37f880c509 Run alloc sync tests b3a6abee448 Improve readability of some fmt code examples af617652e36 Rollup merge of #127320 - ChrisDenton:win-sys, r=Mark-Simulacrum 2f2687dc5bf Rollup merge of #127214 - bjorn3:miri_native_unwind, r=oli-obk a2214d5be9f Describe Sized requirements for mem::offset_of 7975f29759b impl FusedIterator and a size hint for the error sources iter 07e64bf6c1b core: erase redundant stability attrs in va_list 4dfa5547f4a library: outline VaList into ffi::va_list a02e95f3b98 Auto merge of #126171 - RalfJung:simd_bitmask_multibyte, r=workingjubilee b1c90976f64 Document safety of a few intrinsics deb7ecec082 Move a few intrinsics to use Rust abi e236068ee17 mark `can_not_overflow` as `#[rustc_const_stable(...)]` fe2411ed9f8 stabilize `const_int_from_str` f44a456044f Add more checks for pointers with vtable meta bbeb5f34ce2 Improve dead code analysis 82a32915ddd Add comments to windows_targets.rs d00ff096d1a Update windows-bindgen to 0.58.0 73bb9925f72 also remove redundant requirements from offset() df2189a8b5c offset_from: "the difference must fit in an isize" is a corollary d84f4795c81 Rollup merge of #127303 - cuishuang:master, r=jhpratt e8393199bf0 Rollup merge of #127195 - biabbas:vxworks_cleanup, r=jhpratt 4da607d6810 Rollup merge of #126792 - wooden-worm:master, r=Mark-Simulacrum 032d025bc7a chore: remove repeat words 911b053f9d0 impl PathBuf::add_extension and Path::with_added_extension 0852217fe92 Auto merge of #127226 - mat-1:optimize-siphash-round, r=nnethercote ec51024f571 stir the hash state a little to avoid prefix collisions 4eb47316745 Add more test cases for path comparisons 9a67927f412 Add test case demonstrating equality of paths "foo/bar" and "foobar" 7167fa9ba5e Move unique_thread_exit call to lang_start_internal so it is not in a generic function, and wrap it in `catch_unwind` 1ceef6d2dea Remove Miri special-case 50a2dd8142b Use pthread_t instead of numeric thread id 8e7968d80a8 Use libc::pause instead of std::thread::park in wait-for-exit loop 1fcacaffbb6 core: Limit four f16 doctests to x86_64 linux df2fe46e428 std: Set has_reliable_f16 to false for MIPS targets in build.rs 3aa97e587dc library/std/build.rs: "powerpc64le" is not a target_arch 00d9471cf40 Rollup merge of #127204 - dimpolo:stabilize_atomic_bool_fetch_not, r=jhpratt 277c4a673f4 Rollup merge of #123588 - tgross35:stabilize-assert_unchecked, r=dtolnay 6547021de75 Fall back on remove dir implementation for vxworks 149dae95836 Add edge-case examples to `{count,leading,trailing}_{ones,zeros}` methods 9d09b6d9269 Rollup merge of #127230 - hattizai:patch01, r=saethlin 9f956da35a2 chore: remove duplicate words aef7d8c89e6 Optimize SipHash by reordering compress instructions 02f0a8f12d7 Rollup merge of #127128 - elomatreb:elomatreb/stabilize-duration_abs_diff, r=joboet b849207a140 Rollup merge of #126732 - StackOverflowExcept1on:master, r=m-ou-se 4c5d8d9f61b Use the native unwind function in miri where possible db0dd4f9dd3 Avoid MIR bloat in inlining e4e1365e224 Stabilize atomic_bool_fetch_not 2f286f3cd4c Rollup merge of #127182 - danielhuang:patch-4, r=Nilstrieb 01f8bbc0efb Remove unqualified import io:: Error for vxworks as all Error references are qualified in process_vxworks.rs 6b319ef8546 Auto merge of #127026 - Urgau:cleanup-bootstrap-check-cfg, r=Kobzol 6f1fbc09254 LinkedList's Cursor: method to get a ref to the cursor's list e4ee6cb5a1e Update ip_addr.rs 4305dd5a28e Print `TypeId` as hex for debugging ea7fdb5045f Rollup merge of #127069 - Sky9x:fmt-pointer-use-addr, r=Nilstrieb 5f20a377b8e Rollup merge of #126895 - betelgeuse:improve_simd_gather_documentation, r=Amanieu 088170d1511 Rollup merge of #127134 - tgross35:typeid-debug, r=Nilstrieb 652778f18d6 Rollup merge of #126906 - GrigorenkoPV:fixme-split_at_first, r=Mark-Simulacrum adb6b1ed4c7 Rollup merge of #126705 - safinaskar:panic, r=Mark-Simulacrum b17ec877570 Auto merge of #127133 - matthiaskrgr:rollup-jxkp3yf, r=matthiaskrgr f7e63500e22 Print `TypeId` as a `u128` for `Debug` fe16183c67b Rollup merge of #127122 - TDecking:div_ceil, r=Nilstrieb 32716360814 Auto merge of #120639 - fee1-dead-contrib:new-effects-desugaring, r=oli-obk 933b22ab24f Stabilize `duration_abs_diff` a4a45b73b16 small correction to fmt::Pointer impl ca7274e3a6f Auto merge of #127121 - GuillaumeGomez:rollup-xjjjckn, r=GuillaumeGomez 43a96ddcad1 Remove uneccessary condition in `div_ceil` 88515a59f96 Updated docs on `#[panic_handler]` in `library/core/src/lib.rs` 7f74d9fd27f Rollup merge of #127073 - Sky9x:unnecessary-seqcst, r=Nilstrieb 352dfa0e213 Rollup merge of #127072 - Sky9x:docs-includes-vs-does-include, r=scottmcm 6919e8df73a Auto merge of #127119 - RalfJung:miri-sync, r=RalfJung c7bc1208d53 Rollup merge of #126953 - joboet:lazy_key, r=jhpratt cf0367225a3 Merge from rustc 619dcffa150 Rollup merge of #127071 - Sky9x:remove-ptr-to-from-bits, r=scottmcm 4562f597c77 Rollup merge of #127070 - Sky9x:unit-const-param-ty, r=BoxyUwU 9adc037573e Rollup merge of #127055 - shepmaster:hash-finish-must-use, r=dtolnay 3c763bfae95 address review comments 90c4c8fd07d general fixups and turn `TODO`s into `FIXME`s a9d88d58ab2 Implement `Min` trait in new solver 013a508df29 implement new effects desugaring 94cfc38e891 std: add safety comments 308b29c9782 Rollup merge of #126970 - DaniPopes:simplify-str-clone_into, r=cuviper 4c6486672f6 Rollup merge of #126956 - joboet:fmt_no_extern_ty, r=RalfJung baf8dd92f4d Merge from rustc 44c7b44848d Remove unnecessary SeqCst in `impl fmt::Pointer for AtomicPtr` 4046c470f87 docs: say "includes" instead of "does include" 5651dde167a Remove (deprecated & unstable) {to,from}_bits pointer methods a669e5f8672 add () to the marker_impls macro for ConstParamTy 62193d8446f Mark `Hasher::finish` as #[must_use] 850edc75bb4 fix least significant digits of f128 associated constants f32466b2db2 core: improve comment 84b1f32b727 Cleanup bootstrap check-cfg ad1fa261f67 Rollup merge of #126980 - Borgerr:fix-extendfromslice-check, r=workingjubilee a4f9243fe61 Rollup merge of #126929 - nnethercote:rm-__rust_force_expr, r=oli-obk 02d696d32bd Merge from rustc 5f13e2e0915 Auto merge of #126608 - tgross35:f16-f128-library, r=Mark-Simulacrum 7dbd83c86d6 std: test a variety of ways to extend a Wtf8Buf 3a2dc7271c3 set self.is_known_utf8 to false in extend_from_slice b2ed21eaea1 Rollup merge of #126879 - the8472:next-chunk-filter-drop, r=cuviper 20f10d101a5 core: avoid `extern` types in formatting infrastructure 055598e6cba fix UI test, simplify error message 8102e1b6e2d regression test for leaks in the the Filter::next_chunk implementation 055a89820f9 add comments explaining optimizations for Filter::next_chunk 6a94b51b193 fix Drop items getting leaked in Filter::next_chunk cb9a62e8317 Simplify `str::clone_into` 3af1b37306b Rollup merge of #126946 - cyrgani:patch-1, r=compiler-errors cf0725e4b23 Rollup merge of #126927 - workingjubilee:vaargsafe-is-unsafe, r=joboet ceb79985cd9 Rollup merge of #126885 - Borgerr:rm_internal_pathbuf_asmutvec, r=workingjubilee fde69823211 Rollup merge of #126302 - mu001999-contrib:ignore/default, r=michaelwoerister e3e2254d94c Stabilize const unchecked conversion from u32 to char d254c1ae108 std: separate TLS key creation from TLS access 1312f661a06 Detect unused structs which derived Default e51e51a8cdb `PathBuf::as_mut_vec` removed and verified for UEFI and Windows platforms #126333 eac90fa2d84 remove references to `PathBuf::as_mut_vec` in `PathBuf::_set_extension` b72bd2a7d40 inner truncate methods for UEFI platforms 2ad6a1c30ae #126333 remove `PathBuf::as_mut_vec` reference at top of `PathBuf::_push` a75c1dc45f3 simd_bitmask intrinsic: add a non-power-of-2 multi-byte example 586cc8ed6c3 Add missing slash in const_eval_select doc comment 32d6680506c Add tests for `f16` and `f128` 5667599b37d Add more `f16` and `f128` library functions and constants 55606ad9943 Add doctests to existing `f16` and `f128` functions c306c0d50a2 Add build.rs config for reliable `f16` and `f128` 82112e0127b Remove `__rust_force_expr`. 5bfe0bb9631 core: VaArgSafe is an unsafe trait 93feaffaab3 Auto merge of #126852 - scottmcm:more-checked-math-tweaks, r=Amanieu d991b51df8d Check that we get somewhat sane PIDs when spawning with pidfds 8307eb5884b more fine-grained feature-detection for pidfd spawning 82a81db0757 document safety properties of the internal Process::new constructor 02153cf5d24 use pidfd_spawn for faster process creation when pidfds are requested a1236e92fe3 document the cvt methods 715941c0fec Rollup merge of #126904 - GrigorenkoPV:nonzero-fixme, r=joboet 1f533904873 Rollup merge of #125575 - dingxiangfei2009:derive-smart-ptr, r=davidtwco e65f29fd5f2 Rollup merge of #125082 - kpreid:const-uninit, r=dtolnay bee6fcf016d Replace `MaybeUninit::uninit_array()` with array repeat expression. bc3bd2f2be3 Auto merge of #126523 - joboet:the_great_big_tls_refactor, r=Mark-Simulacrum 83727270798 Small fixme in core now that split_first has no codegen issues 987ecb40fd2 Small fixme in core now that NonZero is generic 6cfc3064a28 std: fix wasm builds 3975532f09a Rollup merge of #126213 - zachs18:atomicbool-u8-i8-from-ptr-alignment, r=Nilstrieb 32d120b4f9a Fix simd_gather documentation 9159ed6456d wasm64 build with target-feature=+simd128,+atomics d922ec58a2c Reword docs for `f32` and `f64` ee37324a1cb Extract repeated constants from `f32` and `f64` source 8917842dcfc Rollup merge of #126854 - devnexen:std_unix_os_fallback_upd, r=Mark-Simulacrum 9324968ec0c Rollup merge of #126807 - devnexen:copy_file_macos_simpl, r=Mark-Simulacrum 2a75b1d388f Implement `unsigned_signed_diff` ae532d6040a Also get `add nuw` from `uN::checked_add` a02af5e5f1d SmartPointer derive-macro 88d1cd03b52 fix build edb2b6c7dcd Rollup merge of #126783 - tguichaoua:fix_tcplistener_into_incoming_issue_number, r=workingjubilee 6dde891ceab std::unix::os::home_dir: fallback's optimisation. 1e17ba8f307 Auto merge of #126838 - matthiaskrgr:rollup-qkop22o, r=matthiaskrgr 03a959104d2 Rollup merge of #126552 - fee1-dead-contrib:rmfx, r=compiler-errors c9bc842b768 Rollup merge of #126140 - eduardosm:stabilize-fs_try_exists, r=Amanieu 5f5b1ff3681 Auto merge of #116113 - kpreid:arcmut, r=dtolnay eff61ae806a Generalize `{Rc,Arc}::make_mut()` to unsized types. f43a1367915 Replace `WriteCloneIntoRaw` with `CloneToUninit`. f56ea40a294 Add `core::clone::CloneToUninit`. 554bdf12fbc Auto merge of #126750 - scottmcm:less-unlikely, r=jhpratt 423b03ff9bf Auto merge of #124101 - the8472:pidfd-methods, r=cuviper 11717b1c5a0 to extract a pidfd we must consume the child 623b454e578 Add PidFd::{kill, wait, try_wait} 3350f8a99dd std::unix::fs: copy simplification for apple. 08e0cf97a13 Auto merge of #125853 - tesuji:promote-fail-fast, r=cjgillot 2ca74509a17 update intrinsic const param counting 8ea6ced04ef Remove `feature(effects)` from the standard library 4ba67af6b35 Auto merge of #126781 - matthiaskrgr:rollup-5u4pens, r=matthiaskrgr 24d05cddd72 fix issue number 161475b1a77 Rollup merge of #126613 - tgross35:log-test-update, r=cuviper 0617f9966aa Stop using `unlikely` in `strict_*` methods 209aab44fb2 [GVN] Add tests for generic pointees with PtrMetadata 1e9f268e272 Don't perform mitigation for thread-unsafe libc::exit under Miri. 957b95c00de fix rustdoc URL 644b955b03b On `target_os = "linux"`, ensure that only one Rust thread calls `libc::exit` or returns from `main`. 22e53904579 Auto merge of #126578 - scottmcm:inlining-bonuses-too, r=davidtwco 17a18ac57b2 Auto merge of #124032 - Voultapher:a-new-sort, r=thomcc b748e9e9f96 Rollup merge of #126737 - fee1-dead-contrib:rm-const-closures, r=compiler-errors a96daa000bc Fix wrong big O star bracing in the doc comments fa606e29575 Remove `feature(const_closures)` from libcore dfe88b1a193 Auto merge of #126736 - matthiaskrgr:rollup-rb20oe3, r=matthiaskrgr 9b9bfa0430e Rollup merge of #126717 - nnethercote:rustfmt-use-pre-cleanups, r=jieyouxu b132ef3f12e Rollup merge of #126711 - GKFX:const-option-as-slice, r=oli-obk ef5d0371d0c Auto merge of #116088 - nbdd0121:unwind, r=Amanieu,RalfJung 219197758b0 Stabilize `PanicInfo::message()` and `PanicMessage` cd72cd143d3 Rollup merge of #126703 - the8472:on-blackbox-crypto-use, r=scottmcm 219c67e79df Shrink some slice iterator MIR c9725786eb1 Stabilize `hint_assert_unchecked` f7e1c6098c6 Update documentation for `hint::assert_unchecked` fc7d8fc27ad Add blank lines after module-level `//` comments. 7c93493c34b Add blank lines after module-level `//!` comments. 4f7296e63c2 Convert some module-level `//` and `///` comments to `//!`. dd1a2dd5960 Make Option::as_[mut_]slice const fdc05d99713 reword the hint::blackbox non-guarantees 2ae42a88f55 core: add tracking issue for `array::repeat` 68a298a2602 core: simplify implementation of `array::repeat`, address other nits dfd808d6d3b core: implement `UncheckedIterator` for `RepeatN` ff0308f1a35 core: implement `array::repeat` 6b6d34d92f5 Add a hack to prevent proc_macro misopt in CI 0fbb087b20e Stabilise c_unwind 08c2a368768 Rollup merge of #125787 - Oneirical:infinite-test-a-novel, r=jieyouxu 4ad9e7853c4 try implementing suggestions 0ae3debf63b run_make_support nm implementation + bin-emit-no-symbols rmake rewrite b33acb23e56 Replace `move||` with `move ||` in `compiler/` and `library/` 347bed484f1 Auto merge of #126330 - m-ou-se:panic-message-type, r=Amanieu fe1c6d70792 Print the tested value in int_log tests 2ec0dcc1dfb Add missing CopyMarker impl 7df981a16c8 Revert panic_safe test changes 392eb2c5036 Add PanicMessage type for PanicInfo::message(). 97d0b738762 Add tracking issue to async_drop API cc8fdf14fac std: rename module for clarity c43d3f5a8aa std: update TLS module documentation d22966d4f39 std: use the `c_int` from `core::ffi` instead of `libc` ed498ebed9a std: simplify `#[cfg]`s for TLS 9521b297ae1 Fix unintended regression for Freeze + Copy types aa00eaee245 Auto merge of #126569 - jieyouxu:rollup-1uvkb2y, r=jieyouxu 04f176ea87e Rollup merge of #126531 - slanterns:error_provider, r=workingjubilee 1500fb4cd0f Rollup merge of #126468 - RalfJung:euclid, r=Mark-Simulacrum 3f04b106299 Rollup merge of #126346 - hermit-os:fd, r=Amanieu 1c121834e4e Rollup merge of #126288 - x4exr:patch-1, r=dtolnay b4a76715287 Auto merge of #125720 - folkertdev:optimize_for_size-ptr-rotate, r=Amanieu a22b72748e5 doc: Added commas where needed aac54463664 Fix doc-link issue 2bd62254ac2 Remove reliance on const_trait in sort implementations ab8f4182373 std: move `sys_common::backtrace` to `sys` a5cb9d3b6fe use rustc-dep-of-std in panic_unwind e412625b4d4 Rollup merge of #126539 - lukaslueg:patch-1, r=jhpratt dfcffa9a4b9 Rollup merge of #125112 - tbu-:pr_create_dir_all_empty, r=dtolnay 3911c2d5899 Update `Arc::try_unwrap()` docs 230a662556d Apply review comments 59ba8aa75da Auto merge of #126299 - scottmcm:tune-sliceindex-ubchecks, r=saethlin 3b491522214 Redo SliceIndex implementations 050b7ec2289 update comment 796eccd8352 Rollup merge of #126229 - ChrisDenton:bindgen, r=Mark-Simulacrum 4ba758941a5 std: refactor the TLS implementation 79dab667be3 Auto merge of #126518 - matthiaskrgr:rollup-wb70rzq, r=matthiaskrgr 5c89686c4d0 std: suggest OnceLock over Once 0bef4c2a634 Polish `std::path::absolute` documentation. 595637f2fe4 Auto merge of #126473 - matthiaskrgr:rollup-8w2xm09, r=matthiaskrgr f3051a83bca Rollup merge of #126285 - kpreid:unique-rc, r=dtolnay 11d900f8816 Rollup merge of #126266 - tbu-:pr_doc_alloc_default_system, r=jhpratt abbf2112b6a Rollup merge of #126135 - hermit-os:fuse, r=jhpratt 2972f2a53a9 Rollup merge of #123769 - dtolnay:literal, r=fee1-dead e639ef23ffc div_euclid, rem_euclid: clarify/extend documentation f348b080e64 Rollup merge of #126351 - devnexen:to_sol11_upd, r=ChrisDenton e1317e03295 Rollup merge of #126402 - firefighterduck:fix-unsafe-precon-copy, r=Nilstrieb 7e1d8b6568a Rollup merge of #126390 - Kriskras99:master, r=Nilstrieb 5520081f6e2 Rollup merge of #126360 - compiler-errors:uplift-structural-traits, r=lcnr cf86d65ce3e Rollup merge of #123726 - jieyouxu:command-new-docs, r=Nilstrieb 4e7e205ec84 Remove superfluous escaping from byte, byte str, and c str literals 2d3a3078f60 LangItem-ify Coroutine trait in solvers aa751920c3e fix wrong assert_unsafe_precondition message for core::ptr::copy f22733fe326 Rollup merge of #126384 - RalfJung:is_none_or, r=workingjubilee 7edc31eedb9 Rollup merge of #126347 - slanterns:try_simplify, r=scottmcm a7431703073 Fix wording in {checked_}next_power_of_two c4255c1da74 add tracking issue for is_none_or 70951eaeeb4 std::unix::fs::link using direct linkat call for Solaris and macOs. 57c6d50169f Rollup merge of #126328 - RalfJung:is_none_or, r=workingjubilee 2bf1608998a Simplify `try_*` on `Iterator` dc3124fda83 export std::os::fd module on HermitOS 36b1308c300 Auto merge of #126273 - pietroalbini:pa-bootstrap-update, r=Mark-Simulacrum 177166deb26 add is_none_or a47a03fd14f Rollup merge of #126322 - m-ou-se:panicinfo-and-panicinfo-2, r=RalfJung 3a164e6b7b2 Rollup merge of #126242 - yaahc:simplify-provider, r=jhpratt b49f037a8d3 Rollup merge of #126039 - dpaoliello:arm64ecbuild, r=davidtwco bfa81f1ccb4 Fix deprecated version. b3e786a8d20 Update doc comment on PanicInfo::message(). ecc0b5598cd Use payload_as_str instead of two downcasts. 5dfc44b0ef4 Fix deprecation version. 9c2ed1287df Clarify doc comment. 25a79403286 Auto merge of #126319 - workingjubilee:rollup-lendnud, r=workingjubilee dcaea097224 Rollup merge of #126305 - workingjubilee:fix-os-string-to-string-utf8-invariant, r=joboet 9e35c753d2c Rollup merge of #126287 - nnethercote:reformat-cranelift-patch, r=bjorn3 9c5ea9650b4 Rollup merge of #126281 - ChrisDenton:env, r=jhpratt 5d7064ab2e3 Rollup merge of #126249 - workingjubilee:simplify-try-map-signature, r=scottmcm 83eb4117b96 Rollup merge of #126210 - lolbinarycat:ptr_doctest_assert, r=workingjubilee 30eef188f3d Rollup merge of #123374 - mgeier:doc-slice-from-raw-parts, r=scottmcm fd00adabcbb Require any function with a tait in its signature to actually constrain a hidden type ffdaec89498 Revert "Rollup merge of #125362 - joboet:tait_hack, r=Nilstrieb" 53338949d36 Make PathBuf less Ok with adding UTF-16 then `into_string` fe2978a4fee Update a cranelift patch file for formatting changes. cfd3cab6697 `UniqueRc`: support allocators and `T: ?Sized`. b0bc704e07f set_env: State the conclusion upfront 52590bd3b9d Rename `std::fs::try_exists` to `std::fs::exists` and stabilize fs_try_exists 30d538a7cb1 Unify guarantees about the default allocator bc6b6506bc9 remove cfg(bootstrap) 0f7f807500f replace version placeholder e610b348b96 Formatting. 753e03c0405 Bump deprecation of std's PanicInfo alias to 1.82.0. 36a657629f6 Add PanicHookInfo::payload_as_str(). 4efa6c17d82 Fix display of panic message in recursive panic. a2ef319f8fc Mention core's PanicInfo in error.md. 2de46b56c5e Add note on panic payload type. 82887b712b9 Downcast panic payload to String too in example. 10e1abc6e15 Move deprecation of std::panic::PanicInfo to 1.80.0. f970e47fb0e Fix deprecation version. 247730a857c Rename std::panic::PanicInfo to PanicHookInfo. a71e6ce822e Formatting. 550e0d776f1 Fix invalid markdown/html. 5c0ea2faab4 Reorder body of begin_panic for consistency. 0a9a7fbaa82 Impl Display for PanicPayload to simplify things. ff7f3e05cb5 Use unnamed lifetimes for [..]Payload impl blocks. c00f8aed949 Move downcasting panic payload to str to a function. 1b59d4467a2 Mark some PanicInfo methods as #[inline] for consistency. 5fe76fd6a65 Remove std::panic::PanicInfo::internal_constructor+set_payload. 39707837203 Remove core::panic::PanicInfo::internal_constructor. 0052069655d Update doc comment about core::panicking. 5fb065c45b8 Fix doc link. 36bd9170b5c Add core::panic::PanicInfo::payload() for compatibility. 637e1502949 Document difference between core and std's PanicInfo. fc72f5e60f7 Split core's PanicInfo and std's PanicInfo. 7aad12e29fa Skip fast path for dec2flt when optimize_for_size d29a86eafb8 Simplify `[T; N]::try_map` signature c125d4292cc Simplify provider api to improve llvm ir f94b6812857 Rollup merge of #126212 - SteveLauC:fix/haiku, r=joboet 65c83c23868 Rollup merge of #126191 - ivan-shrimp:nonzero_doc, r=scottmcm 0ff2d0c78ab Bump windows-bindgen to 0.57 47ceb8961bb Clarify `Command::new` behavior if passed programs with arguments 378551759e0 Remove some unused crate dependencies. 9d65aad2b32 Update docs for AtomicU8/I8. 1df95852450 fix: build on haiku 4a1b4b26ab0 Update safety docs for AtomicBool::from_ptr. 00d0668f13e docs(core): make more const_ptr doctests assert instead of printing c33751d2458 Auto merge of #126205 - jieyouxu:rollup-s64z5ng, r=jieyouxu ac223de3a65 Rollup merge of #126194 - ChrisDenton:winerror, r=Mark-Simulacrum d12653fed0e Rollup merge of #125253 - sunsided:feature/FRAC_1_SQRT_PI, r=Mark-Simulacrum 4bb78c5c4e9 Auto merge of #126193 - RalfJung:miri-sync, r=RalfJung d7298a85855 Migrate more things to WinError acb846f4bd3 fix `NonZero` doctest inconsistencies 6f627656fed Rollup merge of #126168 - devnexen:current_exe_haiku_simpl, r=ChrisDenton 578bf7d70ed Rollup merge of #126146 - devnexen:signal_fbsd, r=ChrisDenton 49a1c883ff0 Merge from rustc 40eda39ed17 std::unix::os current_exe implementation simplification for haiku. b0702359bc4 Auto merge of #125966 - schvv31n:impl_os_string_pathbuf_leak, r=workingjubilee ee86ecaf2ed std::unix::process adding few specific freebsd signals to be able to id. e91cbb992da Rollup merge of #126138 - wbk:patch-1, r=lqd c870bd1bc7f Rollup merge of #125998 - devnexen:get_mode_illumos, r=Nilstrieb c618eb083f1 Rollup merge of #125951 - slanterns:error_in_core_stabilization, r=Amanieu fd404e36ee8 Fix typo in docs for std::pin e16df071146 add HermitOS support of vectored read/write operations de554dfae41 Rollup merge of #126089 - wutchzone:option_take_if, r=scottmcm 3c0c4037f9e Rollup merge of #126030 - ChrisDenton:update-wingen-readme, r=Mark-Simulacrum aa2886e4af0 Rollup merge of #124012 - slanterns:as_slice_stabilize, r=BurntSushi ae154652517 Auto merge of #126110 - workingjubilee:backtrace-0.3.73, r=workingjubilee 6f96071b662 Update backtrace to 0.3.73 6c7e982242d Merge from rustc 68a6a33d7b1 Rollup merge of #125606 - diondokter:opt-size-int-fmt, r=cuviper 22a92afa705 fix doc comments about `error_generic_member_access` f85932ad8d6 Stabilize `error_in_core` 38947113154 fixed memory leaks in PathBuf::leak & OsString::leak tests 0df8f9af4cb Rollup merge of #126096 - c410-f3r:tests-tests-tests, r=jhpratt 017325d835b [RFC-2011] Allow `core_intrinsics` when activated b150b7da138 Stabilize Option::take_if 446db91a8c4 less garbage, more examples 26ebc014177 Raise `DEFAULT_MIN_STACK_SIZE` to at least 64KiB ed24a33cc3a Auto merge of #126038 - matthiaskrgr:rollup-h4rm3x2, r=matthiaskrgr 53584cb1f99 Promote `arm64ec-pc-windows-msvc` to tier 2 6cfda43eaa2 Rollup merge of #126032 - ChrisDenton:update-docs, r=joboet 8c9f29232ff Rollup merge of #125800 - fortanix:raoul/rte-99-fix_mut_static_task_queue, r=jethrogb 83a1d42aa54 Rollup merge of #125940 - devnexen:unix_fs_netbsd_get_path, r=cuviper 058f9cce650 Update description of the `IsTerminal` example 91c88ba0710 Update `./x fmt` command 3a2f8b23379 Rollup merge of #125995 - kpreid:const-uninit-stable, r=Nilstrieb d3f57ccb764 Rollup merge of #125982 - xTachyon:fix-linked-list, r=jhpratt 92967ee37bc Rollup merge of #123168 - joshtriplett:size-of-prelude, r=Amanieu e5bbb6154ff std::unix::fs::get_mode implementation for illumos/solaris. 38d3f69cd8b Use inline const instead of unsafe to implement `MaybeUninit::uninit_array()`. db7358336ad Use inline const instead of unsafe to construct arrays in `MaybeUninit` examples. a6351aa1479 Rollup merge of #125932 - schvv31n:patch-1, r=lqd 5f55225a7eb Rollup merge of #125927 - ferrocene:lw-alloc-unwind-test, r=pietroalbini 0469ff1f957 Rollup merge of #125696 - workingjubilee:please-dont-say-you-are-lazy, r=Nilstrieb 8fe2b906ec3 Rollup merge of #106186 - rossmacarthur:ft/iter-chain, r=Amanieu d576318de0b Make deleting on LinkedList aware of the allocator 5ca6c83a28b impl OsString::leak & PathBuf::leak 6ce4d9380f0 Add function `core::iter::chain` 8e3f2ad5adb update tracking issue for `const_binary_heap_new_in` d2dd6b639ed Rollup merge of #125919 - tbu-:pr_fix_typo, r=lqd f91d1b36c3d Rollup merge of #125504 - mqudsi:once_nominal, r=cuviper 3e9dc75b72a Let compiler auto impl `Send` for `Task` 6413fae7bfd Store `Task::p` as `dyn FnOnce() + Send` 897700948ca Pass function for `Thread` as `Send` to `Thread::imp` b66d32538f1 more explicitly state the basic rules of working with the obtained raw pointers 8bb7d148920 Windows: Use futex implementation for `Once` 00ea385b027 Auto merge of #125525 - joboet:tls_accessor, r=cuviper afc305b9a72 std::unix::fs::get_path: using fcntl codepath for netbsd instead. 8220564df04 Fix typo in the docs of `HashMap::raw_entry_mut` fd779ee8363 Ignore `vec_deque_alloc_error::test_shrink_to_unwind` test on non-unwind targets b6aa5ae6e22 Auto merge of #125912 - nnethercote:rustfmt-tests-mir-opt, r=oli-obk 7d763d74183 Remove stray "this" 75f0ce3245b Add "OnceList" example to motivate OnceLock 15450ce98c8 Move first OnceLock example to LazyLock 6d663dca23a Differ LazyLock vs. OnceLock in std::sync overview 503f1279674 Explain LazyCell in core::cell overview 9bd21976f83 Reformat `mir!` macro invocations to use braces. 11900d9f263 Rollup merge of #125898 - RalfJung:typo, r=Nilstrieb c97590df1a2 Rollup merge of #125884 - Rua:integer_sign_cast, r=Mark-Simulacrum c0ba27e599e Rollup merge of #121062 - RustyYato:f32-midpoint, r=the8472 83f934a6425 Wording of the documentation 0bb71b44295 typo: depending from -> on 93735cc0cb1 Auto merge of #125577 - devnexen:netbsd_stack_min, r=joboet ebbd8e8b627 from_ref, from_mut: clarify domain of quantification 02025d3396b Implement feature `integer_sign_cast` 4b9cc07e632 Change f32::midpoint to upcast to f64 9e5e1206d7f Auto merge of #124294 - tspiteri:ilog-first-iter, r=the8472 9557ed2129b stablize `const_binary_heap_constructor` & create an unstable feature `const_binary_heap_new_in` for `BinaryHeap::new_in` 35a5480a99e Rollup merge of #125730 - mu001999-contrib:clippy-fix, r=oli-obk 456eb0f9157 Auto merge of #124662 - zetanumbers:needs_async_drop, r=oli-obk bfd8c93fbf2 Avoid `mut` and simplify initialization of `TASK_QUEUE` 890a7f0022c Auto merge of #124636 - tbu-:pr_env_unsafe, r=petrochenkov b9357cf3709 Rollup merge of #125746 - jmillikin:duration-from-weeks-typo, r=lqd 423851b4add Rollup merge of #125739 - RalfJung:drop-in-place-docs, r=workingjubilee 6f0a5983f93 Rollup merge of #125342 - tbu-:pr_doc_write, r=ChrisDenton 05cfa21ea0d explain what the open questions are, and add a Miri test for that ed7739a6f08 Apply x clippy --fix and x fmt 4a44f6bd413 Fix copy-paste error in `Duration::from_weeks` panic message. 645f0e542bd Rollup merge of #125733 - compiler-errors:async-fn-assoc-item, r=fmease 6a7b5cdb93c Elaborate about modifying env vars in multi-threaded programs ba46834a996 Add note about safety of `std::env::set_var` on Windows 56dc23dc1c5 Make `std::env::{set_var, remove_var}` unsafe in edition 2024 810ef2d4d83 drop_in_place: weaken the claim of equivalence with drop(ptr.read()) dcc8411115a Add lang item for AsyncFnKindHelper::Upvars 988e66fddb4 Add lang item for Future::Output b00df7e0e50 Add lang items for AsyncFn's associated types 7409a38987b [ACP 362] genericize `ptr::from_raw_parts` 1a4b4c1218a Add FRAC_1_SQRT_2PI doc alias to FRAC_1_SQRT_TAU bbdb782e700 make `ptr::rotate` smaller when using `optimize_for_size` 2ebe56e4eb0 Add safety comment to fix tidy dba9a971e50 Optimize async drop glue for some old types d8487ea52a0 Add FRAC_1_SQRT_2PI constant to f16/f32/f64/f128 c0c18b33aeb Rollup merge of #125226 - madsmtm:fix-mac-catalyst-tests, r=workingjubilee b442329195d Rollup merge of #124251 - scottmcm:unop-ptr-metadata, r=oli-obk 2e018b3cb06 Add custom mir support for `PtrMetadata` b68b85fe410 Add an intrinsic for `ptr::metadata` a7fa29d3cbb Rollup merge of #125637 - nnethercote:rustfmt-fixes, r=GuillaumeGomez b1e4122ae46 Make more of the test suite run on Mac Catalyst dcd90f1a2e7 Disable stack overflow handler tests on iOS-like platforms 9f81b5ebec8 Don't format `tests/run-make/*/rmake.rs`. fc0ccec8fe3 Rollup merge of #125647 - tspiteri:track-lazy_cell_consume, r=workingjubilee fc7928e51a4 Rollup merge of #125551 - clarfonthey:ip-bits, r=jhpratt 10ae51aba5a update tracking issue for lazy_cell_consume 16b4b82a257 Auto merge of #125636 - workingjubilee:bump-backtrace-0.3.72, r=workingjubilee c3ec615830a Sync libstd deps with backtrace 12d7e0585f6 Bump backtrace to 0.3.72 5f72e2a76e4 Auto merge of #125609 - diondokter:opt-size-char-count, r=thomcc 82690107e80 Rollup merge of #124870 - Lokathor:update-result-docs, r=dtolnay f2c89e79560 Always use the general case char count db5822c9464 Size optimize int formatting 8645c486e94 Rollup merge of #125559 - scottmcm:simplify-shift-ubcheck, r=workingjubilee 74692ca015c Auto merge of #122079 - tbu-:pr_copy_file_range_probe, r=the8472 407b23bd5af std::pal::unix::thread fetching min stack size on netbsd. 7ed86fde5a4 Auto merge of #125574 - matthiaskrgr:rollup-1oljoup, r=matthiaskrgr 925aa5c3aea Rollup merge of #125571 - tesuji:dummy-pi, r=Nilstrieb 917cb7afdbd Rollup merge of #125561 - Cyborus04:stabilize-slice-flatten, r=scottmcm a2280e4bbd3 Auto merge of #125570 - tesuji:stdout-handle, r=Nilstrieb 6c742cfc200 f32: use constants instead of reassigning a dummy value as PI 7ee5d056097 use proper name instead of magic number c69696b6e82 Stabilize `slice_flatten` a75b87f8367 Auto merge of #125070 - tbu-:pr_set_extension_panic, r=jhpratt 6c96d3c9760 Auto merge of #125518 - saethlin:check-arguments-new-in-const, r=joboet 3d5d6cab872 It seems that anchor names are implicitly all lowercase 0c10397d91a Simplify the `unchecked_sh[lr]` ub-checks a bit 262626fccb4 Fix URL target, it's in the module not the type. ed642d88bd6 github showed that weird. c48b6fb68c6 correct for copy paste errors when fixing wrapping. 6d612cb1480 Resolve https://github.com/rust-lang/rust/pull/124870#issuecomment-2128824959 dbed65de4af revert to the inconsistent paragraph wrapping. 5acd3d1fbe3 Rollup merge of #124667 - newpavlov:stabilize_div_duration, r=jhpratt 82325323fb0 Rollup merge of #123803 - Sp00ph:shrink_to_fix, r=Mark-Simulacrum 74c93529e9a Rollup merge of #122986 - taiki-e:aix-c-char, r=Mark-Simulacrum e17f1508a3b Rollup merge of #121377 - pitaj:lazy_cell_fn_pointer, r=dtolnay e8773689d59 Stabilise ip_bits feature 997e0869662 Auto merge of #121571 - clarfonthey:unchecked-math-preconditions, r=saethlin f82136ffcd2 Rollup merge of #125527 - programmerjake:patch-2, r=workingjubilee e6e78e3bc51 Rollup merge of #125498 - zmodem:avx512er, r=workingjubilee d2490a180d5 Rollup merge of #125478 - Urgau:check-cfg-config-bump-stage0, r=Mark-Simulacrum 79bc3ae7239 Rollup merge of #125271 - RalfJung:posix_memalign, r=workingjubilee 2b4a6eefc29 Move the checks for Arguments constructors to inline const bc59cbc5fb4 Add manual Sync impl for ReentrantLockGuard 5ed337895a8 std: make TLS accessors closures that return pointers f9a7238d2dc Rollup merge of #125497 - meesfrensel:patch-1, r=calebzulawski 40b8bd0506e Auto merge of #125499 - matthiaskrgr:rollup-84i5z5w, r=matthiaskrgr f58afc3efa7 Stop using the avx512er and avx512pf x86 target features 9c77d7890d1 Change pedantically incorrect OnceCell/OnceLock wording f55745b2942 Rollup merge of #125477 - nnethercote:missed-rustfmt, r=compiler-errors c87fbc95b05 Rollup merge of #125455 - blyxyas:opt-clamp, r=joboet 9d1dac03d78 Fix some SIMD intrinsics documentation 3d814c1c4e9 Auto merge of #122494 - joboet:simplify_key_tls, r=m-ou-se 77725a7e735 Auto merge of #121150 - Swatinem:debug-ascii-str, r=joboet 85fc9936297 std: clean up the TLS implementation d91b244ec52 std: simplify key-based thread locals 37997052b67 Auto merge of #125479 - scottmcm:validate-vtable-projections, r=Nilstrieb 36d339d4540 Validate the special layout restriction on DynMetadata 1fc8d14d314 Remove now outdated comment since we bumped stage0 b49da189bcd Run rustfmt on files that need it. 838f458d7f9 Auto merge of #125463 - GuillaumeGomez:rollup-287wx4y, r=GuillaumeGomez bd0204e7f4a Add assert_unsafe_precondition to unchecked_{add,sub,neg,mul,shl,shr} methods 0a2f52ec521 Auto merge of #123724 - joboet:static_tls, r=m-ou-se b6df795e240 Rollup merge of #125452 - Urgau:check-cfg-libraries-cleanup, r=bjorn3 2db0f06ea16 Rollup merge of #125362 - joboet:tait_hack, r=Nilstrieb e957e6329ff Auto merge of #125456 - fmease:rollup-n8608gc, r=fmease 2a26c9b2cc4 Process a single not-ASCII-printable `char` per iteration 5c0c9d404db Rollup merge of #124389 - CensoredUsername:master, r=petrochenkov a4f6da79126 Auto merge of #117804 - saethlin:no-recursive-panics, r=joboet 5037890e3fe Make clamp inline 0190725d1da Copy core/alloc check-cfg message also in std 08fc650f813 Move some expected cfgs to std build.rs as per Cargo recommandation e8189311c2d Replace fake "restricted-std" Cargo feature by custom cfg 16f0759c792 panic_nounwind in Arguments::new* instead of recursing 6bc0e91b332 Expect any feature cfg in core and std crates fbac4bdd132 std: rewrite native thread-local storage d7906eeedfe core: use `Copy` in TAIT to fix clippy lint b04dfaaf031 Rollup merge of #125392 - workingjubilee:unwind-a-problem-in-context, r=Amanieu fdaa18bd790 Rollup merge of #125156 - zachs18:for_loops_over_fallibles_behind_refs, r=Nilstrieb fd2f9a38e4e Auto merge of #125423 - fmease:rollup-ne4l9y4, r=fmease ecff146df31 Rollup merge of #125043 - RalfJung:ref-type-safety-invariant, r=scottmcm 6d06a1483e8 Rollup merge of #125296 - tesuji:checkcfg-buildstd, r=Nilstrieb,michaelwoerister ae61e1e833d Rollup merge of #124896 - RalfJung:miri-intrinsic-fallback, r=oli-obk 3a47b14f6df Auto merge of #117329 - RalfJung:offset-by-zero, r=oli-obk,scottmcm 96448512235 Wrap Context.ext in AssertUnwindSafe fac9493eff3 improve comment wording ef37874743b tidy alphabetica 7e884155d00 addresss reviews 995fe25ca89 Update check-cfg lists for std 8015d3c5b0b Update check-cfg lists for alloc c1218fdd031 Update check-cfg lists for core 3c59fe05cb2 core: actually use TAIT instead of emulating it 28e6b10b4eb Simplify environment variable examples cc58779e439 Auto merge of #125358 - matthiaskrgr:rollup-mx841tg, r=matthiaskrgr c7a6d974b17 Rollup merge of #125348 - tbu-:pr_doc_path_absolute, r=jhpratt 7e770f28adb Rollup merge of #125266 - workingjubilee:stream-plastic-love, r=RalfJung,nikic 7d2260adfe0 Rollup merge of #125225 - madsmtm:ios-crt_externs.h, r=workingjubilee fa344a9f501 Rollup merge of #125011 - diondokter:opt-for-size, r=Amanieu,kobzol b3a31c733e7 Auto merge of #124097 - compiler-errors:box-into-iter, r=WaffleLapkin f2601c23900 Document behavior of `create_dir_all` wrt. empty path 72842ff9bce Implement BOXED_SLICE_INTO_ITER 78e6e776450 Add the impls for Box<[T]>: IntoIterator d34e7af0783 Rollup merge of #125333 - hermit-os:fuse, r=workingjubilee 6246b026c6a Rollup merge of #125123 - a1phyr:fix-read_exact, r=workingjubilee eb4b575254e Rollup merge of #124050 - saethlin:less-sysroot-libc, r=ChrisDenton e9b6ddabd3e Small fixes to `std::path::absolute` docs dfbff9604af switch also the default implementation for read_vectored a7e5c15bd5c Document platform-specifics for `Read` and `Write` of `File` ef58acc1142 switch to the default implementation of `write_vectored` 0fdbeda3810 Remove Windows dependency on libc fa4937ba66a Address review comments 3ad84c34097 Fix c_char on AIX e76440b2f40 Rollup merge of #125283 - zachs18:arc-default-shared, r=dtolnay ff069cf3d27 Switch to primarily using `&str` c2e4240e6c0 Introduce printable-ASCII fast-path for `impl Debug for str` 41573bf6023 Add a fast-path to `Debug` ASCII `&str` 152254672c3 Write `char::DebugEscape` sequences using `write_str` d8959bbf61a Auto merge of #125313 - matthiaskrgr:rollup-65etxv0, r=matthiaskrgr 0de5d95712b Rollup merge of #125093 - zachs18:rc-into-raw-with-allocator-only, r=Mark-Simulacrum 2755dfc6a12 Auto merge of #124560 - madsmtm:update-libc, r=Mark-Simulacrum 259ac9efc90 Make NULL check in argument parsing the same on all unix platforms 927d97827ee Auto merge of #123878 - jwong101:inplacecollect, r=jhpratt 2e3da1e1462 Rollup merge of #124992 - foresterre:example/is-terminal, r=ChrisDenton 63adc220198 Rollup merge of #124948 - blyxyas:remove-repeated-words, r=compiler-errors b337c52d64b fix typo 3fbb749db11 Fix typo in assert message 0ed63d6bd23 cfg-out unused code under no_global_oom_handling a8f41acf187 fmt 76a174652b0 Add example to IsTerminal::is_terminal bad73bd2720 Auto merge of #123786 - a1phyr:cursor_unsafe, r=joboet 74279d1542f Fix stacked borrows violation c58f40702db Use a single static for all default slice Arcs. a2ec88f0b7a Rollup merge of #125252 - beetrees:patch-1, r=joboet 4a586f40983 Rollup merge of #124304 - hermit-os:fuse, r=joboet b08b5f28801 Rollup merge of #123709 - tgross35:windows-cmd-docs-update, r=ChrisDenton 3985dc4e53f use posix_memalign on most Unix targets fa5e305b5ae Auto merge of #124640 - Billy-Sheppard:master, r=dtolnay 7756d97dda3 Add NULL check in argument parsing on Apple platforms 7c51aa7cc45 Auto merge of #99969 - calebsander:feature/collect-box-str, r=dtolnay 5b71466ba99 compiler: add simd_ctpop intrinsic 8fba6d4fffe use `Result::into_ok` on infallible result. 9ca12cca52d specialize `Iterator::fold` for `vec::IntoIter` 73e9a3a8f22 optimize in_place_collect with vec::IntoIter::try_fold 4d9064b4ced optimize in-place collection of `Vec` 065b860e647 Rollup merge of #125251 - jonhoo:patch-1, r=Nilstrieb cd6eb6eb41f Clarify how String::leak and into_boxed_str differ 0764b51d11e Fix typos (taking into account review comments) b1b9550bd9c Add `#[inline]` to float `Debug` fallback used by `cfg(no_fp_fmt_parse)` a033ec8d188 android: use posix_memalign for aligned allocations 535067066a5 Add a warning to Delimiter::None that rustc currently does not respect it. e5790674d3a Inline Duration construction into Duration::from_{millis,micros,nanos} 06ef658e970 Update libc to 0.2.155 45d7bf47281 Use `_NSGetArgc`/`_NSGetArgv` on iOS/tvOS/watchOS/visionOS 1aad51a4830 Use `_NSGetEnviron` instead of `environ` on iOS/tvOS/watchOS/visionOS 820000d7775 Don't call Duration::new unnecessarily in Duration::from_secs 1e094b807d6 Auto merge of #125188 - tgross35:f16-f128-powi, r=Nilstrieb 9144cc105bc Rollup merge of #125186 - Colepng:master, r=lqd c741580838a Rollup merge of #125171 - scottmcm:rename-flatten, r=jhpratt 5f37e98e25b Access alloc field directly in Arc/Rc::into_raw_with_allocator. 3b20f40e348 Auto merge of #125163 - ssukanmi:stdarch_arm_crc32, r=Amanieu 1cc8678d890 Add `powi` to `f16` and `f128` 57801f7de8d Add doctests for f16 and f128 library functions where possible 06b570b9a2f Remove duplicate word from addr docs 8ab3258dbda Auto merge of #124728 - beetrees:from-f16-for-f64, r=BurntSushi 193749a9c83 Fix linkchecker doc errors 0bef7e153a9 Turn bare links into automatic links 9a077fa66af Move BufGuard impl outside of function e7fea15b5e1 Fix tidy errors 1dcb727a45a Replace sort implementations d0365145ddb Auto merge of #124959 - prorealize:update-result-documentation, r=joboet ce80d3e2558 Rename `flatten(_mut)` → `as_flattened(_mut)` 6ca01835eb2 Rollup merge of #125003 - RalfJung:aligned_alloc, r=cuviper eb7e1794107 feat: update stdarch submodule for intrinsics on ARM aca2c00e5c4 Allow for_loops_over_fallibles in test that tests &mut Result as IntoIterator. 9cba1c8fcad Rollup merge of #125038 - ivan-shrimp:checked_sub, r=joboet 78c3b56e11f Rollup merge of #124307 - reitermarkus:escape-debug-size-hint-inline, r=joboet c17b743481a Update library/core/src/result.rs 89a5681d1b4 Divide float nanoseconds instead of seconds 0a37f238ccc avoid using aligned_alloc; posix_memalign is better-behaved cc7d3e1c716 Fix `read_exact` and `read_buf_exact` for `&[u8]` and `io:Cursor` 95671364dfb Rollup merge of #116675 - joshlf:patch-10, r=scottmcm 7940ad52fab Add fn into_raw_with_allocator to Rc/Arc/Weak. 37fb9007a99 Forward alloc features to core 118552287d2 Rollup merge of #123817 - slanterns:seek_relative, r=dtolnay b3833934b2b Don't use `T` with both Result and Option, improve explanation. ee336fb4697 Add `size_of`, `size_of_val`, `align_of`, and `align_of_val` to the prelude b959ec6b1bc Panic if `PathBuf::set_extension` would add a path separator a91d1bab769 offset, offset_from: allow zero-byte offset on arbitrary pointers 7354fa4c940 Use shared statics for the ArcInner for Arc::default, and for Arc<[T]>::default where alignof(T) <= 16. a937feff55f Add note about possible allocation-sharing to Arc/Rc::default. 5991fa059de added Default impls cda43ffadf7 Auto merge of #125045 - GuillaumeGomez:rollup-em6qdzw, r=GuillaumeGomez f7f0f459b39 Rollup merge of #125021 - joshlf:patch-11, r=RalfJung 3d19331077a Auto merge of #124798 - devnexen:illumos_memalign_fix, r=RalfJung 9c5899c6210 Auto merge of #125012 - RalfJung:format-error, r=Mark-Simulacrum,workingjubilee c4493bda1aa reference type safety invariant docs: clarification b4b504ae8f7 reverse condition in `uN::checked_sub` 200f554a2ad Rollup merge of #124981 - zachs18:rc-allocator-generalize-1, r=Mark-Simulacrum 666758ca034 References must also be non-null 2d6d5ff6732 Relax slice safety requirements 2f63707f3de std::alloc: using posix_memalign instead of memalign on solarish. b7bcf1dd652 Auto merge of #124213 - rust-lang:cargo_update, r=Mark-Simulacrum c71cd2e1638 Pin libc back to 0.2.153 4200a20078e io::Write::write_fmt: panic if the formatter fails when the stream does not fail a72afe5fa07 Add flag to sysroot e35b948431c Add flag to std and alloc too 15750d744bb Add opt-for-size core lib feature flag 4a4dcdc0e3e Rollup merge of #124954 - kpreid:fmterr, r=Nilstrieb b6b0173ef66 Rollup merge of #124928 - okaneco:trim_ascii, r=workingjubilee 78912bb0260 Rollup merge of #124991 - Infinixius:patch-1, r=Nilstrieb 2c0d2795ce3 Rollup merge of #124766 - devnexen:getrandom_solarish, r=Mark-Simulacrum a6a8a4c5742 Stabilize `byte_slice_trim_ascii` for `&[u8]`/`&str` 2b27a69396f Fix typo in ManuallyDrop's documentation 9490ccfdf18 Relax A: Clone requirement on Rc/Arc::unwrap_or_clone. 50537091188 Relax allocator requirements on some Rc APIs. 19adaedae40 Add fn allocator method to rc/sync::Weak. Relax Rc/Arc::allocator to allow unsized T. 18d0a1dbe80 Auto merge of #124863 - DaniPopes:from-str-radix-panic, r=Amanieu 3eb5f8652b0 Fix assert 48c299a9e35 Auto merge of #124774 - the8472:subnanosecond-benches, r=jhpratt 43cef411fde Rollup merge of #124551 - Swatinem:debug-str-bench, r=cuviper 7e8f5492a48 Refactor examples and enhance documentation in result.rs ea02f4942ac Document proper usage of `fmt::Error` and `fmt()`'s `Result`. 64a9d6b7fd2 Suggest borrowing on fn argument that is `impl AsRef` 855fd514c20 Auto merge of #124773 - Marcondiro:master, r=joboet 3fb218f125a Improve escape methods. b190f6712ae Auto merge of #124793 - scottmcm:simplify-as-chunks, r=Nilstrieb d8ca2ca83ab Auto merge of #124910 - matthiaskrgr:rollup-lo1uvdn, r=matthiaskrgr ea208397a07 Rollup merge of #124892 - jfgoog:update-cc, r=workingjubilee a563a04f6f6 Avoid panicking branch in `EscapeIterInner`. 76632d1bf2a Inline `EscapeDebug::size_hint`. 35e06ca7570 Auto merge of #124795 - scottmcm:simplify-slice-from-raw-parts, r=joboet cdd5b17e96f Use generic `NonZero`. e7151898394 Use generic `NonZero` in examples. d75eae05ded miri: rename intrinsic_fallback_checks_ub to intrinsic_fallback_is_spec 00d931ab184 Update cc crate to v1.0.97 0ec54b3e598 fix #124714 str.to_lowercase sigma handling ea63e117d4c Rollup merge of #124838 - RalfJung:next_power_of_two, r=scottmcm 35d92c7b0e4 Rollup merge of #124788 - madsmtm:reduce-target_os-macos, r=workingjubilee 799a2644b06 Rollup merge of #124782 - anatawa12:docs-create-new-already-exists, r=workingjubilee cc6a88c4235 Rollup merge of #124470 - devnexen:no_sigpipe_fbsd, r=workingjubilee 2389f0166cd use teletype on the attribute name 303b4b13320 Some Result combinations work like an Option. 6833098e0ff from_str_radix: outline only the panic function b60a15b81f6 Move `test_shrink_to_unwind` to its own file. 3a933cda71f Fix `VecDeque::shrink_to` UB when `handle_alloc_error` unwinds. 0f42ca9469a Auto merge of #124836 - tgross35:const-slice-last-chunk, r=BurntSushi dc6f017636c next_power_of_two: add a doctest to show what happens on 0 8d6b8f9e397 Correct the const stabilization of `last_chunk` for slices 6bdba469a88 f16::is_sign_{positive,negative} were feature-gated on f128 6ad2824f670 Auto merge of #124811 - matthiaskrgr:rollup-4zpov13, r=matthiaskrgr 84f45e5209f Rollup merge of #124520 - tbu-:pr_create_dir_all_doc, r=Amanieu 3e816cd857b Auto merge of #123850 - tspiteri:f16_f128_consts, r=Amanieu 3c670a883c3 std::rand: adding solaris/illumos for getrandom support. c0aae312b78 Auto merge of #124497 - rytheo:move-std-tests-to-library, r=workingjubilee d8b12529a33 Avoid a cast in `ptr::slice_from_raw_parts(_mut)` ffb6092744e Implement `as_chunks` with `split_at_unchecked` ffac31cca51 iOS/tvOS/watchOS/visionOS: Improve File Debug impl bc335de4d02 iOS/tvOS/watchOS/visionOS: Fix reading large files 85047c5b28c iOS/tvOS/watchOS: Fix alloc w. large alignment on older versions f3d4d35bab2 iOS/tvOS/watchOS/visionOS: Set the main thread name 0d9e2d3486e Apply suggestions from code review b2010f0abaa iOS/tvOS/watchOS/visionOS: Default to kernel-defined backlog in listen d1e16e44de0 add note about `AlreadyExists` to `create_new` 0eefb74b4e4 emit fractional benchmark nanoseconds in libtest's JSON output format f015b0f1a6e print walltime benchmarks with subnanosecond precision eed82316d51 alloc: implement FromIterator for Box adb6ecbaffe Rename test for issue 21058 63bc1cd6523 Rollup merge of #124750 - ultrabear:ultrabear_softfloatdoc, r=workingjubilee 9d57b94d295 Rollup merge of #124749 - RossSmyth:stable_range, r=davidtwco f7c0cf06f4d Fix unwinding on 32-bit watchOS ARM 1db8462191e Re-add `From for f64` 589ac364764 Make f128 docs mention lack of any normal platform support 7584b01e9a3 Make f16 and f128 docs clearer on platform support 7463b1dc452 Tgross feedback tweaks 20abd2ed612 Rollup merge of #124721 - ids1024:netbsd-32-bit-ulong, r=workingjubilee ff05d6ac60a library/std: Fix build for NetBSD targets with 32-bit `c_long` 99bec4f2944 Rollup merge of #124699 - scottmcm:split_at_unchecked_should_use_unchecked, r=Nilstrieb 5310f8200ac Rollup merge of #122441 - a1phyr:improve_read_impls, r=ChrisDenton 49a3a08f89b Rollup merge of #124701 - scottmcm:unchecked_sub_docs, r=Nilstrieb 9c584488855 Rollup merge of #124700 - scottmcm:unneeded_cast, r=Nilstrieb ed65709261c Rollup merge of #124293 - oli-obk:miri_intrinsic_fallback_body, r=RalfJung 7d61045797b Rollup merge of #124159 - joboet:move_pal_thread_parking, r=ChrisDenton 09b960f4e56 Rollup merge of #123356 - joboet:set_current_size, r=ChrisDenton cb2e87d5160 Docs: suggest `uN::checked_sub` instead of check-then-unchecked d89b2ef99d7 Remove an unnecessary cast 4a48f91b775 Use `unchecked_sub` in `split_at` 2f081700f4b mark const_(de)allocate intrinsics as suitable for Miri 9f66d50e541 Rollup merge of #124681 - risc0:erik/fix-test, r=joboet 50ed58a5bd6 Rollup merge of #124678 - UserIsntAvailable:feat/stabilize-split-at-checked, r=jhpratt 8cc83b3cf03 Rollup merge of #124480 - Enselic:on-broken-pipe, r=jieyouxu fdb55240bdd feat: stabilize `split_at_checked` 46ab3a5a02e Rollup merge of #124593 - GKFX:cstr-literals-in-api-docs, r=workingjubilee 3219bcea092 Rollup merge of #124059 - RalfJung:default_alloc_error_hook, r=workingjubilee deb794e7f7d Rollup merge of #123815 - trueb2:patch-1, r=workingjubilee 54e7a2b60a6 Rollup merge of #122492 - GrigorenkoPV:ptr_as_ref_unchecked, r=workingjubilee fc8b72bf03f default_alloc_error_hook: explain difference to default __rdl_oom in alloc a11afb258d0 Use `CURRENT_RUSTC_VERSION` cc4d3d54d7b Stabilize `div_duration` 065fca09f90 Rollup merge of #124649 - Meziu:master, r=ChrisDenton df710576168 Ensure miri only uses fallback bodies that have manually been vetted to preserve all UB that the native intrinsic would have aacfee5dc93 Horizon OS: dirfd unavailable e7c007f3990 Rollup merge of #124626 - RalfJung:const_eval_select, r=joboet d6f6b7c3120 Rollup merge of #124609 - RalfJung:float-precision, r=cuviper 309284d0184 Rollup merge of #124604 - Enselic:std-gimli-symbolize, r=workingjubilee c62ba4ca56d Rollup merge of #124441 - bravequickcleverfibreyarn:string.rs, r=Amanieu b75a4ef2423 Rollup merge of #124412 - RalfJung:io-safety, r=Amanieu f5b26d64ebc Rollup merge of #123480 - Nadrieril:impl-all-derefpures, r=compiler-errors 678151494ee Stabilize exclusive_range fecd98ecb67 Update based on review 8d458dc81bb Change `SIGPIPE` ui from `#[unix_sigpipe = "..."]` to `-Zon-broken-pipe=...` 1a3dbe8851a variable-precision float operations behave non-deterministically a4c2108ac6b const_eval_select: add tracking issue c12885f3fb1 add constants in std::f128::consts 13e6bc77c5e add constants in std::f16::consts 880f2adb4cf add f128 associated constants fa0d9e41d36 add f16 associated constants 370ad11c1e6 Auto merge of #124419 - WaffleLapkin:never-type-fallback-docs, r=workingjubilee 8ae0903fa87 std: move thread parking to `sys::sync` c4199310239 library/std: Remove unused `gimli-symbolize` feature d0385f2acf7 fixup links in never type docs 7e70f0b61cc Workaround rustfmt bug replacing type ascription 6fad5c1640f Slightly reformat !'s docs after applying github suggestions ebb77a6e2f5 Step bootstrap cfgs 5fd23bc388d Apply suggestions from code review a0f28c008a3 Replace version placeholders for 1.79 787db3f03d0 Describe and use CStr literals in CStr and CString docs 77ecdee5d4f Rollup merge of #124542 - CBSpeir:diagnostic-item-enumerate-method, r=scottmcm 80f9320e2c2 Add benchmarks for `impl Debug for str` 84238e3cffc Auto merge of #124491 - madsmtm:target_vendor-apple, r=workingjubilee 83776465b61 std: rewrite TLS on platforms without threads bfd20ed8d83 Add diagnostic item for std::iter::Iterator::enumerate 8bb4d9c2bad Rollup merge of #124530 - djkoloski:fuchsia_dirfd, r=tmandry 112a022b746 Document that `create_dir_all` calls `mkdir`/`CreateDirW` multiple times d90886b971c Rollup merge of #124484 - GKFX:offset_of_must_use, r=jieyouxu 539ecc5de0d Fix Fuchsia build broken by #124210 3ddc456cae2 Fix ESP IDF build broken by #124210 a8e3e693271 Auto merge of #124502 - NCGThompson:statically-known-docs, r=jhpratt 1efbc540f1f Update is_val_statically_known docs 706a02ce340 Run tidy on tests 1d76049fbfc Stabilize `non_null_convenience` 93a312ce3d8 Fix posix_spawn not being used on iOS and visionOS f188a7dddb2 Move various stdlib tests to library/std/tests e13c814ae57 Fix va_list on watchOS and visionOS 65118dd4f52 Fix SIGEMT and SIGINFO parsing on watchOS and visionOS 1ed06511886 Fix available_parallelism on watchOS and visionOS 0149b26dde2 Fix #124478 - offset_of! returns a temporary fe426fc873a std::net: Socket::new_raw set to SO_NOSIGPIPE on freebsd/netbsd/dragonfly. a39a459e519 Use `target_vendor = "apple"` instead of `target_os = "..."` da91ea9ff38 Auto merge of #124210 - the8472:consign-ebadf-to-the-fire, r=Mark-Simulacrum cb7df0d0253 put FD validity behind late debug_asserts checking 9e4ae45cce3 Rollup merge of #124447 - workingjubilee:set-argv-twice-on-gnu, r=ChrisDenton 6b6731a567c Unconditionally call really_init 2d3e5aedcce Lift the probe code of `copy_file_range` into a function c473dcb7ec5 Elaborate in comment about `statx` probe b4397fefeae WS fix. 1c27f80e4c7 String.truncate calls Vec.truncate, in turn, and that states "is greater or equal to". Beside common sense. b10059ec0f9 Auto merge of #124432 - zetanumbers:non_copy_into_raw_with_alloc, r=Nilstrieb 084a861a7ce Relax `A: Clone` bound for `rc::Weak::into_raw_and_alloc` dc0888ca5bb io safety: update Unix explanation 27c28c055bb Rollup merge of #124387 - workingjubilee:use-raw-pointers-in-thread-locals, r=joboet 49beec813cb thread_local: refine LazyKeyInner::take safety doc ded08c73c12 Rollup merge of #124410 - RalfJung:path-buf-transmute, r=Nilstrieb 938bb80eddd Apply suggestions from code review d241015600a Add missing .into_iter() ef3cb548ef9 Extend the example code and assert the result 53af5028076 Document never type fallback in `!`'s docs 94a0ff6ca32 Add "safety" comment 9b9717d1c99 Auto merge of #123909 - dtolnay:utf8chunks, r=joboet 0f03b894240 PathBuf: replace transmuting by accessor functions 16a152b39a0 Auto merge of #124393 - scottmcm:do-the-macros-still-matter, r=joboet 89c14694f0e Convert some iter macros to normal functions 6a18dcc60d2 Rollup merge of #124076 - NobodyXu:patch-1, r=dtolnay bf62ba2d8ea thread_local: split refs to fields of Key 1e2bca1f836 thread_local: use less &mut T in LazyKeyInner::take 50d96826bba remove trivial bounds 67e25b21715 Stabilize Utf8Chunks ce9191a8884 Rollup merge of #124351 - Treeniks:master, r=workingjubilee a67e3bfe8e3 Rollup merge of #124335 - ChrisDenton:stabilize-absolute, r=dtolnay f3af73bc67e Rollup merge of #124322 - whosehang:master, r=Nilstrieb 8fe18a84a52 fix typo in binary_heap docs c46572b06d8 Auto merge of #124330 - fmease:rollup-a98y7jf, r=fmease 27a2721edc2 Fix cannot usage in time.rs cbb57d74e20 Stabilize `std::path::absolute` f06b6a56ffc Add `cfg_attr(bootstrap)` to doc tests a52dfe83c32 Stabilise `inline_const` 10c88f18dbe Rollup merge of #124308 - CBSpeir:diagnostic-item-enumerate, r=compiler-errors 3605bd01ccf Rollup merge of #124282 - RalfJung:fill_utf16_buf, r=ChrisDenton 02dc45d34ce Rollup merge of #124281 - RalfJung:win-tls, r=joboet 648304c9ad4 Error on using `yield` without also using `#[coroutine]` on the closure c8f5bdd2fb5 chore: fix some typos in comments c0194ba5cd5 Add diagnostic item for std::iter::Enumerate c85e59813fc increase the readability by using the unique name for the hermit-abi 4458a06852b Auto merge of #124302 - matthiaskrgr:rollup-2aya8n8, r=matthiaskrgr fbca6b6bae5 Rollup merge of #124003 - WaffleLapkin:dellvmization, r=scottmcm,RalfJung,antoyo f714d0262cb revise the interpretation of ReadDir 5f32b938701 Rollup merge of #123048 - RalfJung:layout, r=dtolnay ca05155abba unroll first iter of checked_ilog loop to save one multiplication e15b9e87ebd Rollup merge of #123050 - RalfJung:panic_str, r=m-ou-se 5cee930c562 fix weak memory bug in TLS on Windows fa7e4759c06 windows fill_utf16_buf: explain the expected return value d795186ab7e Rollup merge of #124266 - RalfJung:no-answer, r=joboet a6b89311e3d Auto merge of #121801 - zetanumbers:async_drop_glue, r=oli-obk c4e9f4e8e1f Rollup merge of #124230 - reitermarkus:generic-nonzero-stable, r=dtolnay 5b2c124c584 Rollup merge of #115913 - FedericoStra:checked_ilog, r=the8472 e4a2a9ac46f remove an unused type from the reentrant lock tests a45683987ec export assert_unsafe_precondition macro for std-internal use 9e8436908d7 Stabilize generic `NonZero`. 3b88e540457 Rollup merge of #124246 - gurry:add-comma-in-abs-doc, r=jhpratt a14fb979752 Add comma at one place in `abs()` documentation f894b066cf5 Update stdarch submodule b9032dacd07 Address more PR feedback 528bf87f608 Use it in the library, and `InstSimplify` it away in the easy places 0c70112da04 Add an intrinsic that lowers to AggregateKind::RawPtr d3058318aa0 Rollup merge of #124184 - gurry:124152-suggest-unsigned-abs-in-abs-doc, r=jhpratt 7bdbf7fce2a Rollup merge of #124089 - simlay:fix-preadv64-and-pwritev64-link-for-watchos-and-visionos, r=workingjubilee 6f8ff1d9ce1 Fix watchOS and visionOS for pread64 and pwrite64 calls 19a54235148 Auto merge of #123930 - Mark-Simulacrum:vec-length-invariant, r=jhpratt 596bad9a51e Avoid reloading Vec::len across grow_one in push 2c27c9d90d8 Auto merge of #124208 - jieyouxu:rollup-gbgpu4u, r=jieyouxu 17f5be2c036 Abort a process when FD ownership is violated 96a589f124a Rollup merge of #124103 - dtolnay:metadatadebug, r=Mark-Simulacrum 36145abf0cf Rollup merge of #123976 - ChrisDenton:no-libc-in-std-doc-tests, r=Mark-Simulacrum 1dd75733ed4 Rollup merge of #123967 - RalfJung:static_mut_refs, r=Nilstrieb 08cf3028aeb Auto merge of #122013 - Swatinem:unicode-gen-fastpath, r=scottmcm c167a511ebc Add a lower bound check to `unicode-table-generator` output e557b8e2980 Suggest using `unsigned_abs` in `abs` documentation 6228e299e1c Auto merge of #124114 - scottmcm:better-checked, r=workingjubilee 52420a280e9 Rollup merge of #124116 - RalfJung:miri-rust-backtrace, r=Nilstrieb 50e7263eced Rollup merge of #124019 - ChrisDenton:futex-raw-dylib, r=joboet 5187ad24212 Rollup merge of #123406 - krtab:fix_remainder_iterchunk, r=scottmcm 3bd11d6069a Make `checked` ops emit *unchecked* LLVM operations where feasible 93856c91753 Auto merge of #123144 - dpaoliello:arm64eclib, r=GuillaumeGomez,ChrisDenton,wesleywiser 6cff2a9740b when suggesting RUST_BACKTRACE=1, add a special note for Miri's env var isolation c5655c4fb0c Improve std::fs::Metadata Debug representation cd9f723021b fix: make `str::from_raw_parts_mut` mut 8481d220b41 Rollup merge of #124049 - slanterns:const_io_structs_stabilize, r=jhpratt b1b535eecb8 Rollup merge of #122201 - coolreader18:doc-clone_from, r=dtolnay cb5efbfe146 Stablise io_error_downcast b14eae95d09 Address comments 108b077f39b Rollup merge of #124051 - dtolnay:emptyset, r=compiler-errors 173b05d02b9 Fix empty-set symbol in comments 88acf73afb0 Stabilize `const_io_structs` 03ded04bbec Rollup merge of #124013 - RalfJung:box-to-raw, r=oli-obk 36396a20218 Rollup merge of #123859 - krtab:uneeded_clone, r=cuviper 74ecfdf79ec Rollup merge of #123811 - joboet:queue_em_up, r=ChrisDenton 83d3c4229c4 Add simple async drop glue generation 03e205b2950 Use raw-dylib for Windows futex APIs 32a4b15b5d1 std: fix lint on SGX ca5ef336179 Remove uneeded clones now that TrustedStep implies Copy 939ff7335d8 Rollup merge of #123721 - madsmtm:fix-visionos, r=davidtwco 189ae80f137 Stabilize `BinaryHeap::as_slice` 7f5617bbfc3 Box::into_raw: make Miri understand that this is a box-to-raw cast 2dc289f073b Update usage note on OpenOptions::append() 53992b0d6c9 Change intrinsic types to use `u32` instead of `T` to match stable reexports 9a0949263cf Add support for Arm64EC to the Standard Library 499c82ea22c Rollup merge of #123970 - risc0:erik/zkvm-fix-os-str, r=joboet 9c0e01abc5b Use fake libc in core test 5e7b9197aba Auto merge of #123968 - jieyouxu:rollup-1pnkxor, r=jieyouxu 256ccc82722 static_mut_refs: use raw pointers to remove the remaining FIXME 0216693ce83 zkvm: fix references to `os_str` module 0d624775f4e Rollup merge of #123957 - RalfJung:create_dir_all_bare, r=joboet ef8032789cf Rollup merge of #123548 - RalfJung:what-is-time, r=joboet e43ef7758c4 Auto merge of #123937 - RalfJung:miri-link-section, r=oli-obk fa550fb060a Auto merge of #123851 - NobodyXu:patch-1, r=BurntSushi fc9216870e7 Update doc for std::io::Error::downcast ab7f60d2e4c Remove bound checks from `BorrowedBuf` and `BorrowedCursor` methods 5d9bf2297d3 disable create_dir_all_bare on all(miri, windows) 9a7ebcd2d7d libtest: also measure time in Miri 629dcfc09d5 Auto merge of #123928 - tbu-:pr_statx_enosys, r=workingjubilee 6af07d37722 Add vec_deque::Iter::as_slices and friends 1669ffab029 Rollup merge of #123915 - shenawy29:patch-1, r=Nilstrieb 1a2244cc19f Rollup merge of #120900 - marcospb19:std-use-seek-stream-position, r=joshtriplett 17cb2789a3a Miri: run .CRT$XLB linker section on thread-end 73a43e263d3 `statx` probe: `ENOSYS` might come from a faulty FUSE driver fa61ab022f1 Auto merge of #122268 - ChrisDenton:no-libc, r=Mark-Simulacrum 891647aae8e improve documentation slightly regarding some pointer methods b1186945b18 Move msvc libs to core 1fb95833fa6 Replace libc::c_int with core::ffi::c_int 763a563844d Rollup merge of #123879 - beetrees:missing-unsafe, r=Mark-Simulacrum cac590819ce Rollup merge of #123875 - Ghamza-Jd:master, r=joboet 5161fe658c7 Rollup merge of #123779 - semarie:notgull-openbsd-socket, r=Mark-Simulacrum e0d14821be5 Rollup merge of #123651 - tgross35:thread-local-updates, r=Mark-Simulacrum 53bb6357acf Auto merge of #107462 - WaffleLapkin:from_iterator_for_tuple, r=dtolnay bc34b69759c Auto merge of #123819 - joboet:fmt_usize_marker, r=Mark-Simulacrum a20b82f178e Rollup merge of #123876 - dpaoliello:backtrace, r=ChrisDenton b111bb22fc7 Rollup merge of #123716 - Kriskras99:patch-2, r=Mark-Simulacrum 00df64d2fc8 doc note that f16 and f128 hardware support is limited c182faf5a79 Rollup merge of #123868 - eduardosm:stabilize-slice_ptr_len, r=jhpratt 73954955a38 Rollup merge of #123835 - saethlin:vec-from-nonnull, r=the8472 529625ec1f0 Add missing `unsafe` to internal `std::thread::Thread` creation functions c13b3528806 Add missing `unsafe` to internal function `std::sys::pal::unix::thread::min_stack_size` 75a7a210540 Update backtrace submodule 7d79c6da7c5 chore: replace x with y for hexa-decimal fmt 1a0e9762797 Avoid more NonNull-raw-NonNull roundtrips in Vec 545f4c0ac9b Rollup merge of #123867 - eduardosm:unsafe-fns, r=ChrisDenton 7df628f41dc Rollup merge of #123858 - marijanp:fix-zkvm-cmath-path, r=joboet f16b681c3df Rollup merge of #123857 - devnexen:tcp_listener_update_backlog, r=ChrisDenton d92654c94df Rollup merge of #123807 - joboet:sys_common_thread, r=jhpratt 301c44d7d37 Stabilize (const_)slice_ptr_len and (const_)slice_ptr_is_empty_nonnull f047a37e280 Add `unsafe` to two functions with safety invariants 4a1a24b3e0c zkvm: remove cmath b3521080a32 std::net: TcpListener shrinks the backlog argument to 32 for Haiku. fd780c784c7 Rollup merge of #123852 - kamaboko123:fix_typo_in_std_lib_rs, r=lqd 72a4ccc8061 Rollup merge of #123833 - dpaoliello:stdarch, r=Amanieu 155ff1dc3fe Rollup merge of #123825 - saethlin:report-nounwind-panics, r=petrochenkov c4d785d46f5 Auto merge of #123846 - matthiaskrgr:rollup-85y28av, r=matthiaskrgr 48937213c43 Update document for std::io::Error::downcast 3a6afcf0130 fix typo in library/std/src/lib.rs 6c332685db8 Rollup merge of #123842 - ShockYoungCHN:master, r=scottmcm e5a72348ec7 Rollup merge of #123830 - tgross35:f16-f128-from-inference-fix, r=Nilstrieb 527ab5d4dc4 Auto merge of #123783 - tgross35:f16-f128-debug-impl, r=Amanieu 24399433ff8 core: get rid of `USIZE_MARKER` 5ebeb66d65a Avoid panicking branch in `append_to_string` 4268ce31f14 `VecDeque::read_to_string`: avoid making the slices contiguous ee477720791 Improve several `Read` implementations 02da5d513a6 Auto merge of #123490 - niluxv:strict_prov_unwind_seh, r=Amanieu 41c8eebe194 fix pin.rs typo 25d9d976b29 Rollup merge of #123826 - kornelski:one-in-a-quintillion, r=Amanieu c79bfaaae0a Auto merge of #120092 - zetanumbers:pin_in_static_allocator, r=Amanieu cc53426a799 Update stdarch submodule 524fe01de22 Remove `From` impls for unstable types that break inference 5decc2a2b17 Auto merge of #123823 - matthiaskrgr:rollup-8zdtggx, r=matthiaskrgr 832fee935e4 Call the panic hook for non-unwind panics in proc-macros 22489f92551 Move rare overflow error to a cold function c1d7f16bd71 Rollup merge of #123806 - joboet:advanced_overflow, r=Amanieu 2a7ef05cfd7 Rollup merge of #123798 - tniessen:patch-1, r=workingjubilee 8dd3921d395 Rollup merge of #122882 - Zoxc:panic-output-panic, r=Amanieu 266b991326d Auto merge of #123814 - matthiaskrgr:rollup-lxn0t4t, r=matthiaskrgr d572c23266a Add a `Debug` impl and some basic functions to `f16` and `f128` 4e07d4a02c8 Refactor `panic_unwind/seh.rs` pointer use; x86 now conforms to strict-provenance 7fbb62bff3e Stabilize `Seek::seek_relative` b91f6ef1d7e Auto merge of #123732 - a1phyr:io_error_factor, r=cuviper 041cf545a19 std: use queue-based `RwLock` on Windows 7 9391a38b026 std: use queue-based `RwLock` on Xous ca4c062ead7 std: use queue-based `RwLock` on SGX 1f4e8b6ae60 std: remove `sys_common::thread` 64c866c3407 core: panic on overflow in `BorrowedCursor` 74bb982675d Avoid invalid socket address in length calculation d2b3b9c9885 OpenBSD fix long socket addresses 4c9eb7ea486 Factor some common `io::Error` constants c774fbfdba6 Correct broken link in core::pin doc ca989a1ad55 Rollup merge of #123756 - lukas-code:file-sync, r=jhpratt 7d5a8664ebd Rollup merge of #123661 - tgross35:stabilize-cstr_count_bytes, r=dtolnay acb7744740e Rollup merge of #123360 - adamgemmell:dev/adagem01/restricted-std, r=ehuss dc9ebd284fc Rollup merge of #122470 - tgross35:f16-f128-step4-libs-min, r=Amanieu e11f41e58ea clean up docs for `File::sync_*` b167ebc4c28 Add primitive documentation for `f16` and `f128` 877082f5bab Add basic f16 and f128 modules 8dd2578a112 Add basic library support for `f16` and `f128` 272ac397f1c Revert "Put basic impls for f16 and f128 behind cfg(not(bootstrap))" a83c6fd057b Auto merge of #123725 - GuillaumeGomez:rollup-gk2bbrg, r=GuillaumeGomez 870848a2a17 Rollup merge of #123534 - ChrisDenton:name, r=workingjubilee e8a7e6316ec visionOS: Fix unused import warning 7fbbd417902 Rework Path::ancestors documentation to remove unwraps cc5d0a029a9 Auto merge of #122393 - a1phyr:specialize_read_buf_exact, r=joboet c734f93c68c Bring documentation of Path::to_path_buf in line with the rest of Path/PathBuf 3aa847156bf Auto merge of #122812 - dtolnay:mode, r=workingjubilee 59b0e5d0c0d Update documentation related to the recent cmd.exe fix 9a668e96dad Rollup merge of #123633 - bjorn3:unsupported_command_data, r=jhpratt a9e58dab283 Show mode_t as octal in std::fs Debug impls ba92907c212 Add comment on UTF-16 surrogates 5ce65425b27 Windows: set main thread name without reencoding 434e1a399f5 Add const UTF-8 to UTF-16 conversion macros e54d5924346 Auto merge of #123683 - pietroalbini:pa-cve-2024-24576-nightly, r=pietroalbini a38281894c0 Auto merge of #123485 - madsmtm:use-libc-copyfile, r=joboet c7182cf8d17 Fix dead code warning 31c61db0d4e Rollup merge of #123665 - Jules-Bertholet:patch-1, r=lqd 489209f0264 Rollup merge of #123254 - stepancheg:thin-box-0-const-alloc, r=oli-obk a0b19c74ee7 Fix typo in `Future::poll()` docs 7dfc4bf73f6 Stabilize `cstr_count_bytes` f83a4c8074c Document Windows argument splitting 65dabe4386d Disallow or quote all specials in bat args 2644ae83b56 Change method calls to using the method directly fe63a312fc4 Add `SAFETY` comments to the thread local implementation e0b69523783 Update thread local docs with idiomatic cell type use 61e35d60501 Rollup merge of #123564 - scottmcm:step-by-div-zero, r=joboet e9d871650b2 Auto merge of #120131 - oli-obk:pattern_types_syntax, r=compiler-errors de2ef736b27 Store all args in the unsupported Command implementation 99a36064a8b Rollup merge of #123595 - balaganesh102004:master, r=joboet 180736d582d Rollup merge of #123089 - Philippe-Cholet:vecdeque_pop_assume_cap, r=Nilstrieb f994d0f7df5 Rollup merge of #115984 - hermit-os:fuse, r=m-ou-se b2eb2c1c753 Add pattern types to parser b1697d0e4f4 std: update abort message in `thread::set_current` e058390b7e5 Add invariant to VecDeque::pop_* that len < cap if pop successful 11c3c80812d Auto merge of #123506 - RalfJung:miri-test-libstd, r=Mark-Simulacrum f3a18504b90 Auto merge of #123597 - Gbd199:patch-1, r=jhpratt e437bf0ae65 Fix typo in library/core/src/iter/traits/iterator.rs f4e655375a7 Made changes in documentation e1812501da2 Auto merge of #123592 - matthiaskrgr:rollup-3k1pq8s, r=matthiaskrgr 7ac26bd5405 Auto merge of #123561 - saethlin:str-unchecked-sub-index, r=scottmcm f9c29afe7de sys_common::thread_local_key: make a note that this is not used on Windows 7cf79361f98 make a doctest less slow in Miri 1774e052ef7 also test parts of std 55819afc71b disable benches in Miri 1499ddacff7 Rollup merge of #123522 - dtolnay:constatomicintoinner, r=Nilstrieb 47f1f736208 Rollup merge of #123411 - saethlin:ub-checks, r=Urgau,RalfJung e4084a15982 Rollup merge of #119224 - Duckilicious:test_main_memory_leak, r=cuviper 1e1b7435ed1 Don't emit divide-by-zero panic paths in `StepBy::len` 0a6f8b8d996 Use unchecked_sub in str indexing 6622eb34bae Drop panic hook after running tests c69c4999744 Rollup merge of #123541 - RalfJung:remove-old-hacks, r=Mark-Simulacrum d569a3ca349 Put checks that detect UB under their own flag below debug_assertions 00e28074106 Rollup merge of #122291 - lilasta:stabilize_const_location_fields, r=dtolnay 4837eaeee4e Rollup merge of #114788 - tisonkun:get_mut_or_init, r=dtolnay 3712c8c17a3 remove miri-test-libstd hacks that are no longer needed ab5e33d3835 Rollup merge of #123528 - dtolnay:asyncgeninternals, r=compiler-errors c903120db62 Hide async_gen_internals from standard library documentation 4bc82d83c02 Auto merge of #123433 - GnomedDev:remove-threadname-alloc, r=joboet f38bc8dc587 Stabilize const Atomic*::into_inner 08edf914da3 Rollup merge of #123505 - ChrisDenton:revert-121666, r=workingjubilee bb176bcb14f Rollup merge of #121419 - agg23:xrOS-pr, r=davidtwco 4191c46744f Do not allocate for ZST ThinBox attempt 2 (using const_allocate) ac53cae502c Auto merge of #123317 - RalfJung:test-in-miri, r=m-ou-se,saethlin,onur-ozkan 5bf7094c927 Revert #121666 f86b031013d macOS: Use `libc` definitions for copyfile 5a88f6eb3be Rollup merge of #123206 - stepancheg:pointee-metadata-freeze, r=Amanieu 12162a39647 Remove rt::init allocation for thread name e87eaacc6d7 Impl `DerefPure` for more std types f51cea9e256 Rollup merge of #123431 - slanterns:literal_byte_character_c_string_stabilize, r=dtolnay 7dfa10d296f Rollup merge of #123389 - ChrisDenton:dont-panic-on-startup, r=joboet 96464c85b0f Add comments about using debug_assert f66fd45fada force exhaustion in iter::ArrayChunks::into_remainder 645a778f880 Rollup merge of #122356 - devnexen:dfbsd_build_fix, r=jhpratt 4946b99c64b Stabilize `Literal::c_string` 27edfa7b0ed Stabilize `Literal::byte_character` d357ac37605 Rollup merge of #122964 - joboet:pointer_expose, r=Amanieu d74b1af7dc8 add 'x.py miri', and make it work for 'library/{core,alloc,std}' ed17cc4371e Add docs for `FromIterator<(AE, BE)> for (A, B)` ed184e08934 Implement `FromIterator<(AE, BE)>` for `(impl Default+Extend, impl Default+Extend)` 9f63da69d25 rename `expose_addr` to `expose_provenance` 548e666753f std: add comment about abort motivation 49e188a5aa9 Auto merge of #123390 - tgross35:f16-f128-libs-basic-impls-bootstrap, r=jhpratt 40379477337 Rollup merge of #123388 - tshepang:consistency, r=jhpratt 832e20e43be Rollup merge of #122411 - alexcrichton:wasm32-wasip2-cabi-realloc, r=m-ou-se ac77c491439 Rollup merge of #123203 - jkarneges:context-ext, r=Amanieu 82eabc86f85 Rollup merge of #122935 - RalfJung:with-exposed-provenance, r=Amanieu b581b4b8282 set tracking issue 5f0ff567e5b Auto merge of #123385 - matthiaskrgr:rollup-v69vjbn, r=matthiaskrgr 24ff2cf3946 Put basic impls for f16 and f128 behind cfg(not(bootstrap)) b2265eaa801 Avoid panicking unnecessarily on startup f4b6d399df3 use a consistent style for links bfae1c382fa Rollup merge of #123226 - scottmcm:u32-shifts, r=WaffleLapkin ecfde8d8447 Rollup merge of #123198 - krtab:build_hasher_default_const_new, r=Amanieu 9bdf0e55269 Auto merge of #118310 - scottmcm:three-way-compare, r=davidtwco 29e14999eba DOC: Add FFI example for slice::from_raw_parts() 6aeadff4d8d Document restricted_std d7942baa4da std: reduce code size of `set_current` 12703d7e4a7 style: fmt 4cfd5bb1fb8 fix: build on haiku by adding missing import 7d4e4fc1ac5 Auto merge of #122945 - andy-k:sorted-vec-example, r=jhpratt bd4e928a265 Rollup merge of #123323 - devnexen:thread_set_name_solaris_fix, r=workingjubilee 805e8997f5f std::thread: set_name change for solaris/illumos. 4ebf56457b8 Auto merge of #123315 - devnexen:thread_get_name_solaris, r=ChrisDenton 126de9a1d34 Auto merge of #123265 - joboet:guardians_of_the_unix, r=ChrisDenton 5ee89551b46 update comment ef2261cc570 std::thread: adding get_name implementation for solaris/illumos. 457ab89bc56 Fix error message for `env!` when env var is not valid Unicode b9ddb60232c Auto merge of #123270 - JaniM:janim/string-alloc-doc, r=workingjubilee 79418f3a1b5 doc: mention heap allocation earlier in String docs dd02adf74e6 Auto merge of #123299 - workingjubilee:rollup-2z8amaj, r=workingjubilee 46fd806b65d Rollup merge of #123271 - JaniM:janim/sliceindex-doc, r=Nilstrieb 58ca3f88bc3 Rollup merge of #123268 - RalfJung:dont-freeze, r=Nilstrieb d16c4262949 warn against implementing Freeze 2be41a7f856 std::thread: adding get_name haiku implementation. 021c0ffd2e3 doc: describe panic conditions for SliceIndex implementations 5ee19084e92 catch_panic: warn about panicking payload drop 35f9f96c506 std: move `thread::current` TLS variable out of `thread_info` f69e99e4b33 std: move UNIX stack overflow guard page handling into `stack_overflow.rs` a07e464607f Auto merge of #123233 - devnexen:thread_get_name_bsd, r=joboet 61b76b927a9 Require Pointee::Metadata to be Freeze 8b75ce1812f Auto merge of #123181 - stepancheg:pointee-metadata-debug, r=the8472,Amanieu 69038b4f959 Auto merge of #123085 - tgross35:f16-f128-step4.0-libs-basic-impls, r=Amanieu f80f114db3f Auto merge of #99322 - GKFX:const-int-parse, r=Mark-Simulacrum 6934b96c022 std::thread: adding freebsd/netbsd to the linux's get_name implementation. 582b750f0ae Rollup merge of #123201 - Wilfred:patch-2, r=Nilstrieb 23f7459ddd0 Make {integer}::from_str_radix constant ec58ff86793 De-LLVM the unchecked shifts [MCP#693] 6a785ec728e Auto merge of #121948 - Gankra:stab-align, r=dtolnay 2278f5def73 Auto merge of #122976 - caibear:optimize_reserve_for_push, r=cuviper 91819f3393f stabilize ptr.is_aligned, move ptr.is_aligned_to to a new feature gate ab8c6f20e46 Auto merge of #122520 - scottmcm:stabilize_unchecked_math_basics, r=jhpratt c5b3360a28e rustfmt be14b4b3172 Auto merge of #121268 - Urgau:improve_ambi_wide_ptr_cmps, r=Nadrieril b07397a3a4a Add `Context::ext` 15734760ca8 Improve wording in std::any explanation 32ca4c9ccd1 Add fn const BuildHasherDefault::new fda2b68a62b Add detection of [Partial]Ord methods to the ambiguous wide ptr cmp lint 604e0d97437 Add diagnostic items for Ord and PartialOrd methods 8241bb73a8f Auto merge of #122616 - Jules-Bertholet:casemappingiter-layout, r=Nilstrieb 0457dd08f25 Require Debug for Pointee::Metadata 99355003815 Auto merge of #122975 - DianQK:simplify_ub_check, r=saethlin 79f81aaade4 Auto merge of #122671 - Mark-Simulacrum:const-panic-msg, r=Nilstrieb 4e09bd87d0a Rename reserve_for_push to grow_one and fix comment. e78e1aef1df Fix previous. 2e7fd04901d Remove len argument from RawVec::reserve_for_push because it's always equal to capacity. Also make Vec::insert use reserve_for_push. 3ac35c330f8 Add basic trait impls for `f16` and `f128` a803db89a56 Rollup merge of #123164 - Marcondiro:unicode15-1, r=Manishearth b3ec81aea4b Bump Unicode printables to version 15.1, align to unicode_data fdc26d871eb Rollup merge of #123139 - scottmcm:simpler-nonzero-get, r=jhpratt c22eb88d69a Rollup merge of #123136 - Vagelis-Prokopiou:fix/docs, r=ChrisDenton 5b921a1d43e Rollup merge of #123133 - xiaoxiangxianzi:master, r=fmease 09242e9095a Rollup merge of #121943 - joshlf:patch-11, r=scottmcm 08c88b148c3 `num::NonZero::get` can be 1 transmute instead of 3 97af3d8b244 Less generic code for Vec allocations bbc0a63a3e8 Some wording improvement a44926b9a06 chore: fix some comments da7981513fe Eliminate `UbCheck` for non-standard libraries bd3a3403c37 Auto merge of #123128 - GuillaumeGomez:rollup-3l3zu6s, r=GuillaumeGomez 7695591bcf8 Rollup merge of #123083 - klensy:clippy-me, r=workingjubilee 964ba553bd6 impl get_mut_or_init and get_mut_or_try_init for OnceCell and OnceLock c4105c22776 Auto merge of #116016 - jhpratt:kill-rustc-serialize, r=ehuss 5791e85813c Rollup merge of #123118 - tgross35:rwlock-docs, r=workingjubilee 0b672dbef29 Rollup merge of #123107 - avandesa:vec_pop_if, r=joboet a9800c55ca5 Rollup merge of #123084 - a1phyr:unixstream_read_buf, r=workingjubilee 8e25b61209a Rollup merge of #123038 - he32:netbsd-ilp32-fix, r=workingjubilee bb18d38d498 Rollup merge of #122880 - a1phyr:preadv_more_platform, r=workingjubilee 316007cf13f Update `RwLock` deadlock example to not use shadowing f8759aac861 Implement `Vec::pop_if` be321b90368 Rollup merge of #123057 - sthibaul:systemtime, r=jhpratt 72e4c17d17b Rollup merge of #122835 - compiler-errors:deref-pure, r=Nadrieril 4ebdd0d09ef Rollup merge of #123086 - ding-young:fix-ref-to-BufWriter, r=the8472 554ae64f669 unix fs: Make hurd and horizon using explicit new rather than From 25b86521d11 Auto merge of #122939 - joboet:proc_macro_bridge_state, r=petrochenkov af80edb0f96 Unix: Support more platforms with `preadv` and `pwritev` 97f92c1d114 `UnixStream`: override `read_buf` 3c9398fbc31 Fix link to BufWriter 9512f4c39d6 std library unix/thread.rs: fix NetBSD code for ILP32 CPUs. e72eab3734a panic_str only exists for the migration to 2021 panic macros 2c120ace360 Extract helper, fix comment on DerefPure b648442d12a Require DerefPure for patterns c8bfd9f1c33 Rollup merge of #123042 - dpaoliello:prelude, r=Nilstrieb bba8827f6e6 Rollup merge of #122896 - dpaoliello:stdarch, r=Amanieu 049be22e9c9 Rollup merge of #122707 - reedwoodruff:string_docs_typo, r=workingjubilee 0b17f1f839d lib: fix some unnecessary_cast clippy lint 9db66e953bb Import the 2021 prelude in the core crate 4e278912cdd alloc::Layout: explicitly document size invariant on the type level 8658916d340 Rollup merge of #122990 - SkiFire13:transmute-may-copy, r=jhpratt ce1cf742141 Address PR feedback 0060de353e3 Amended wording 30d9df21d70 Slightly simplify the `iN::partial_cmp` MIR 941425e8641 Rollup merge of #122992 - devnexen:available_parallelism_sol_upd, r=Amanieu e24fa7b8f26 Rollup merge of #122984 - RalfJung:panic-in-hook, r=Amanieu b7078a265b3 Rollup merge of #122983 - taiki-e:bsd, r=workingjubilee d0c205c554f Rollup merge of #122977 - cuviper:as_statically_known_str, r=RalfJung 539545f16e3 fix build. e5b947f8ee0 std::thread: refine available_parallelism for solaris/illumos. f547c84b52d Clarify transmute example 02320250c83 panic-in-panic-hook: formatting a message that's just a string is risk-free d30270df3e4 Fix build failure on ARM/AArch64/PowerPC/RISC-V FreeBSD/NetBSD 2b78b1894a1 Add+Use `mir::BinOp::Cmp` c9227a0c416 Rollup merge of #122797 - alexcrichton:fix-compile-wasm64, r=Mark-Simulacrum 0cc1d873a77 Rollup merge of #122762 - RoboSchmied:RoboSchmied-typo, r=workingjubilee b4aba2d1137 Rollup merge of #120419 - Ayush1325:uefi-sys-os, r=nicholasbishop,workingjubilee a272aa133e0 Rename `Arguments::as_const_str` to `as_statically_known_str` adb7068f73b Auto merge of #122966 - matthiaskrgr:rollup-20k8nsm, r=matthiaskrgr 600be480780 clarify equivalency of binary_search and partition_point c83ccbfb3f2 Rollup merge of #122963 - RalfJung:core-panicking, r=m-ou-se 729fe7fe46a Rollup merge of #122379 - RalfJung:int2ptr-transmute, r=m-ou-se 66111527c66 Auto merge of #122905 - dpaoliello:sync-portable-simd-2024-03-22, r=workingjubilee 9284f99afea Fixed builds with modified libc d9c585f1f70 also rename the SIMD intrinsic 7aa09ad55ba Auto merge of #122629 - RalfJung:assert-unsafe-precondition, r=saethlin d172422e740 core/panicking: fix outdated comment 7ec43390548 try adding a test that LowerHex and friends don't panic, but it doesn't work 35fff274f4e refactor check_{lang,library}_ub: use a single intrinsic, put policy into library 196df605764 move assert_unsafe_preconditions to its own file 7d8ef6ea4fe Auto merge of #122947 - matthiaskrgr:rollup-10j7orh, r=matthiaskrgr 1a448d0c727 Rollup merge of #122931 - herobs:patch-1, r=joboet 808bef8d9f4 Rollup merge of #122930 - RalfJung:panic-in-panic-fmt, r=Amanieu 00a32c0e92d Rollup merge of #122916 - MultisampledNight:docs-sync-typo, r=jhpratt 80f7f6010a8 Rollup merge of #120577 - wutchzone:slice_split_at_unchecked, r=m-ou-se cb3847965d1 Auto merge of #122582 - scottmcm:swap-intrinsic-v2, r=oli-obk f44a47bf6de improve example on inserting to a sorted vector to avoid shifting equal elements 80a041a0ec6 rename ptr::from_exposed_addr -> ptr::with_exposed_provenance b5a67c064ff proc_macro: simplify bridge state 36a3b227899 Fix some typos in the pin.rs fe27550e4b3 add panic location to 'panicked while processing panic' 07c718553dd Auto merge of #119552 - krtab:dead_code_priv_mod_pub_field, r=cjgillot,saethlin 2048c6fd9a8 Merge commit 'cff979eec1ac0473fc4960ee6cde462c6aeda824' into sync-portable-simd-2024-03-22 3de0f715e2c docs(sync): normalize dot in fn summaries efed257ef13 Remove RustcEncodable/Decodable from 2024 prelude 35999897a5e Soft-destabilize `RustcEncodable`/`RustcDecodable` 4502becc618 Update stdarch submodule e09c7beb241 `swap_simple` no longer needs to be a separate function 1a42d52e17a Avoid a panic in `set_output_capture` in the default panic handler b2a8f48597a Codegen const panic messages as function calls 4f0438fbb71 Rollup merge of #122800 - zachs18:nonnull-slice-is_empty, r=Amanieu a911a9e8d48 Auto merge of #122024 - clubby789:remove-spec-option-pe, r=jhpratt 5878ee2a84a Rollup merge of #122829 - ShoyuVanilla:gen-block-impl-fused-iter, r=compiler-errors fb58991de6c Rollup merge of #122817 - ultrabear:ultrabear_btreedoc, r=Nilstrieb 9db330b9494 Rollup merge of #121881 - devnexen:bsd_acceptfilter, r=Amanieu ea8764ecdf5 Not insta-stable fcd95202e85 Auto merge of #122785 - the8472:const-select-specialized-impl, r=Amanieu afc15589fbf Implement `FusedIterator` for `gen` block 43940604b16 Implement macro-based deref!() syntax for deref patterns 11d8db7a239 Stabilize `const_caller_location` and `const_location_fields` 0daed64cc28 Rollup merge of #122806 - compiler-errors:type-ascribe, r=fmease e4e12b3a5c1 document into_iter in top level docs iterator ordering guarantees 95752449add document iteration ordering on into_iter method instead of IntoIterator implementation 6cd7f7f61ae BTree(Set|Map): Guarantee that `IntoIter` will iterate in sorted by key order 91ce0de48d5 Make type_ascribe! not a built-in 38717db7a0c Rollup merge of #122765 - workingjubilee:test-for-vec-handling-usize-max, r=Nilstrieb 664361a0a8a Rollup merge of #122729 - m-ou-se:relax, r=Amanieu 56ef81c815e Add `NonNull::<[T]>::is_empty` as insta-stable. 0405a6718ab Fix compile of wasm64-unknown-unknown target 79f20993f97 Auto merge of #122761 - jwong101:fix/vec-insert, r=workingjubilee,Nilstrieb 245e281d572 select Vec::from_iter impls in a const block to optimize compile times fc4e6242ec8 std::net: adding acceptfilter feature for netbsd/freebsd. 8e6a0034820 Update target.rs alloc.rs event.rs simd.rs 00d9c3ef6f6 SeqCst->Relaxed in condvar test. 0658401e63f SeqCst->Relaxed in thread local test. 371f3dc7c48 SeqCst->Relaxed in std::net::test. 6cf538e3b48 Use less restricted memory ordering in xous::thread_local_key. e786b94d57c Auto merge of #122754 - Mark-Simulacrum:bootstrap-bump, r=albertlarsan68 a93af954cff step cfgs 481a1403b40 Auto merge of #120717 - compiler-errors:cap-closure-kind, r=oli-obk 63ddfd7e1b9 improve codegen of fmt_num to delete unreachable panic 0de5b5b84f9 Add usize::MAX arg tests for Vec ccc702b2364 Rollup merge of #122739 - Sky9x:insert-put, r=jhpratt bdaf4e52781 Rollup merge of #122730 - ferrocene:hoverbear/qnx-ucred-cfgs, r=Amanieu 2d72094ee93 Rollup merge of #121543 - onur-ozkan:clippy-args, r=oli-obk 70ab497b60d fix OOB pointer formed in Vec::index ec17843374a branch 1.78: replace-version-placeholder 9b9b3745c61 resolve clippy errors e886877945d Only split by-ref/by-move futures for async closures 850641443e1 Add "put" as a confusable for insert on hash map/set 20a633cb06d Rollup merge of #122720 - heisen-li:offset_of, r=workingjubilee 608ee212e1a Manually implement `PartialOrd`/`Ord` for `Option` 2af19bf6419 Remove `SpecOptionPartialEq` e4312e32efd Expose ucred::peer_cred on QNX targets to enable dist builds c55036f18f7 SeqCst->Relaxed for xous set_nonblocking. 070f176f93f SeqCst->{Release,Acquire} for xous DropLock. 5cdc89ff9da SeqCst->Relaxed in pal::windows::pipe. 4b20e188ea0 SeqCst->{Release,Acquire} for wasm DropLock. b93974e8659 SeqCst->{Release,Acquire} in sys_common::thread_local_key. d39fef1ce0d Use less restricted memory ordering in thread_parking::pthread. 3eacb323679 SeqCst->{Release,Acquire} in xous mutex. 476f3d73eb9 SeqCst->Relaxed for FIRST_PANIC. 00cffdbe712 SeqCst->{Release,Acquire} for alloc error hook. 44eec322ac4 SeqCst->Relaxed for proc_macro bridge counter. 7674ef73fbe SeqCst->Relaxed in panic_unwind/emcc. 49a93d0a217 SeqCst->Relaxed in doc examples. 9ceb1377705 [doc]:fix error code example b482e5c602c Make ptr_guaranteed_cmp a rustc_intrinsic and favor its body over backends implementing it 626df9e7592 Make `vtable_align` a rustc_intrinsic 704aa351a17 Make `const_eval_select` a rustc_intrinsic 51229a66564 add notes on how to store 'ptr or int' 80c23fb1d38 Support for visionOS 3f118e1d2d1 Reimplement `CaseMappingIter` with `core::array::IntoIter` ebff960ddc3 Auto merge of #122055 - compiler-errors:stabilize-atb, r=oli-obk 3a505690a01 Rollup merge of #122675 - tmfink:doc-clarify, r=scottmcm 856cacbfbb1 Rollup merge of #122642 - pallix:improve-wording-for-vec-swap_remove, r=Amanieu 47455b22a69 Fix a typo in the alloc::string::String docs 23ada9425f9 remove retag_box_to_raw, it is no longer needed e1ea77ce9eb add_retag: ensure box-to-raw-ptr casts are preserved for Miri 01cb63aa2b8 Let codegen decide when to `mem::swap` with immediates fc5dc6836da Improve wording of `Vec::swap_remove` 293f0c586e8 chore(121952): echo comments on the `*_assign` methods 9958c4741f1 chore(121952): remove redundant comments e40edbffd52 feat: implement `{Div,Rem}Assign>` on `X` ca741fc9b6a Rollup merge of #119411 - yotamofek:array-ptr-get, r=Nilstrieb c797a5fe60c core: document default attribute stabilization 0b892445dd1 Optimize `core::char::CaseMappingIter` layout 21f19d5244e Auto merge of #121885 - reitermarkus:generic-nonzero-inner, r=oli-obk,wesleywiser 80ed7d13b71 Rollup merge of #122601 - joboet:ptr_replace, r=workingjubilee 00fdda9b9bd Add as_(mut_)ptr and as_(mut_)slice to raw array pointers 4ea27dd5f12 Rollup merge of #122583 - Zoxc:tls-non-mut, r=joboet cf77b8979a1 Rollup merge of #122390 - ChrisDenton:bindgen, r=Mark-Simulacrum a11146cde70 core: optimize `ptr::replace` 3208298b185 Use `UnsafeCell` for fast constant thread locals 3fea446feda Rollup merge of #122562 - Wilfred:break_keyword_docs, r=workingjubilee 4b189608c9e Workaround issue 122566 e8100e779c7 Mention labelled blocks in `break` docs 41524d0cbd8 Rollup merge of #122512 - baitcode:2024-03-14-buffer-documentation-fix, r=Nilstrieb 013c2b63593 Stabilize `unchecked_{add,sub,mul}` 0c6840c55c2 Auto merge of #122511 - matthiaskrgr:rollup-swzilin, r=matthiaskrgr 343e31f4d1f Use rust-lang/backtrace-rs@6fa4b85 584b50c3f94 Rollup merge of #122498 - jfgoog:update-cc-crate-version, r=workingjubilee 99211d65cce Rollup merge of #122479 - GrigorenkoPV:duration_millis_float, r=scottmcm bf08b6256e2 Rollup merge of #121650 - GrigorenkoPV:cap_setgid, r=Amanieu 1bcff410f01 Fix minor documentation issue. Code outside the test would fail. Seek documentation clearly states that negative indexes will cause error. Just making the code in the example to return Result::Ok, instead of Result::Error. deef36871e5 Update version of cc crate 12a4f5782d3 Hide implementation details for `NonZero` auto traits. c536d353cfd Rollup merge of #119029 - dylni:avoid-closing-invalid-handles, r=ChrisDenton 67d34cdc8de Implement ptr_as_ref_unchecked (#122034) df04d309d27 Auto merge of #122483 - matthiaskrgr:rollup-n07dsh5, r=matthiaskrgr 9aa5a2813c2 Rollup merge of #122461 - the8472:fix-step-forward-unchecked, r=Amanieu 9167f1da76d Rollup merge of #122421 - CAD97:step-trait-docs, r=jhpratt fd302d4be1c Rollup merge of #104353 - clarfonthey:cstr-bytes-iter, r=cuviper 2debeb10aea Auto merge of #114038 - Stargateur:108277, r=ChrisDenton 577830a2855 fix unsoundness in Step::forward_unchecked for signed integers bc862c9debc Implement `Duration::as_millis_{f64,f32}` d96cdc6118c Provide `cabi_realloc` on `wasm32-wasip2` by default a07f7835072 Get wasm32-wasip2 compiling with its custom pal implementation 3601955125e Rollup merge of #122386 - joboet:move_pal_once, r=jhpratt 45ad5c51f01 Rollup merge of #122255 - Nadrieril:min_exh_pats-libs, r=scottmcm 0750b3d1453 Improve Step docs df3c1fa2ad8 Reduce unsafe code, use more NonNull APIs per @cuviper review f1a08330d80 Specialize many implementations of `Read::read_buf_exact` 7f77de63b0a transmute: caution against int2ptr transmutation b5679819aa5 Convert [u8] to [i8] in test fda1dc279de Bump windows-bindgen to 0.55.0 d67519c5206 Bump windows-bindgen to 0.54.0 b9449771bfa std: move `Once` implementations to `sys` 85b9845b423 Fix typo in lib.rs of proc_macro 31946b8c5b6 Allow dead code in sys/pal fecc5271eda Allow dead code in thread local dtor df1322e8bbe Remove unused fields in some structures e1a6c6419f1 Use `min_exhaustive_patterns` in core & std cfc8dc36818 std::rand: fix dragonflybsd after #121942. 20095c13bd1 Auto merge of #122036 - alexcrichton:test-wasm-with-wasi, r=oli-obk b047163178b libtest: Print timing information on WASI 831f55fff37 Rollup merge of #121438 - coolreader18:wasm32-panic-unwind, r=cuviper 41d9a120d2c Auto merge of #122331 - jhpratt:rollup-cbl8xsy, r=jhpratt 79071f1dd28 Rollup merge of #122326 - Zoxc:win-alloc-tweak, r=ChrisDenton e6f2a74cf54 Rollup merge of #122298 - RalfJung:raw-vec-into-box, r=cuviper 24a2605caf2 Rollup merge of #122002 - devnexen:thread_stack_netbsd_fix, r=workingjubilee,riastradh 44d36f4a095 Rollup merge of #121840 - oli-obk:freeze, r=dtolnay dca4c76039d Rollup merge of #121633 - ChrisDenton:precise, r=Nilstrieb 89e13f3dbda Rollup merge of #121148 - clarfonthey:try-range, r=dtolnay e08ba92938a Auto merge of #117156 - jmillikin:os-unix-socket-ext, r=Amanieu,dtolnay 4459c8eacb7 Optimize `process_heap_alloc` 16ef24eb0a6 Auto merge of #122312 - matthiaskrgr:rollup-0p8y7gg, r=matthiaskrgr accb268314c Rollup merge of #122302 - ratmice:issue122234, r=cuviper 219c4b86573 Rollup merge of #122277 - RalfJung:BorrowedCursor, r=cuviper dd5b0d6a897 Rollup merge of #122276 - RalfJung:io-read, r=Nilstrieb 77f848eb409 Rollup merge of #122275 - RalfJung:std-oom, r=workingjubilee 4e68ec0bc1c Add CStr::bytes iterator 5f347f414de Update backtrace submodule to 0.3.70 be41df9f7e1 docs: Correct ptr/ref verbiage in SliceIndex docs. 20486b68dda RawVec::into_box: avoid unnecessary intermediate reference 33fdb0b54ad Fix lint. 8faf2929679 Move generic `NonZero` `rustc_layout_scalar_valid_range_start` attribute to inner type. dc87c2eda8f Rollup merge of #122271 - pitaj:diag_items-legacy_numeric_constants, r=Nilstrieb d6005f7fbdc Rollup merge of #122244 - tvallotton:local_waker_leak_fix, r=Nilstrieb c7aabc3533f Rollup merge of #121942 - devnexen:getrandom_for_dfbsd, r=joboet ed6d065a1c9 Rollup merge of #113525 - workingjubilee:handle-dynamic-minsigstksz, r=m-ou-se 81cf9339aa3 Rollup merge of #112136 - clarfonthey:ffi-c_str, r=cuviper e6b9739a27c BorrowedCursor docs clarification c9b2739bd0b io::Read trait: make it more clear when we are adressing implementations vs callers d4ddd99d39b disable OOM test in Miri 9ef15f16f07 fix legacy numeric constant diag items b6e96d8c02f Auto merge of #121662 - saethlin:precondition-unification, r=RalfJung 93910cb2e17 Rollup merge of #121711 - ChrisDenton:junction, r=Mark-Simulacrum ea8ae947fa8 Rollup merge of #121403 - kornelski:io-oom, r=dtolnay 27e5cb9dec9 Rollup merge of #121280 - ajwock:maybeuninit_fill, r=Amanieu 38436dd87ed Rollup merge of #120504 - kornelski:try_with_capacity, r=Amanieu 008b987bc64 Rollup merge of #114655 - nbdd0121:io-safety, r=dtolnay 1016b26c5a6 Rollup merge of #99153 - Dajamante:issue/95622, r=dtolnay 3f578d92860 Explain why we don't use intrinsics::is_nonoverlapping 8f2b2d3cb4c fix: remove memory leak due to missing drop implementation for local waker. Also, fix some of the stability attributes of LocalWaker's methods. 9155457d1f3 NonZero::from_mut_unchecked is library UB 0df74e26812 Avoid closing invalid handles aff4823c951 Improve docs 20d5fbe3465 Rollup merge of #122233 - RalfJung:custom-alloc-box, r=oli-obk 4b17ce7ac22 Rollup merge of #122232 - RalfJung:misc, r=jhpratt 325b7f3906c Rollup merge of #121358 - GnomedDev:lower-align-typeid, r=Mark-Simulacrum 9ba0c169002 miri: do not apply aliasing restrictions to Box with custom allocator fb0c4ffeb8b fn is_align_to: move some comments closer to the cast they refer to eec7df61e3a fix warning when building libcore for Miri 483c3e6fa67 Auto merge of #122095 - lukas-code:windows-shutdown-test, r=ChrisDenton 056d02f62bc Distinguish between library and lang UB in assert_unsafe_precondition c095b04df7c further changes from feedback b8bf2997c8f Stabilize associated type bounds 6972a0dbcb6 Rollup merge of #121201 - RalfJung:align_offset_contract, r=cuviper 47da96e682f Document overrides of `clone_from()` a1c040e32b0 align_offset, align_to: no longer allow implementations to spuriously fail to align 1845ea0157e Rollup merge of #122099 - Urgau:btreemap-inline-new, r=Amanieu 125b13c3fc4 Rollup merge of #121938 - blyxxyz:quadratic-vectored-write, r=Amanieu a9c51d817d6 Rollup merge of #120608 - kornelski:slice-ptr-doc, r=cuviper b19f8b9e91a Rollup merge of #118623 - haydonryan:master, r=workingjubilee f689614f4a4 Auto merge of #122059 - nyurik:with-as-const-str, r=cuviper 9a8b5610c9c Rollup merge of #122147 - kadiwa4:private_impl_mods, r=workingjubilee 331f09ad186 Rollup merge of #119888 - weiznich:stablize_diagnostic_namespace, r=compiler-errors 93eabe6134c make `std::os::unix::ucred` module private 4bae3ab88ad Rust is a proper name: rust → Rust 711876afc1d Auto merge of #122113 - matthiaskrgr:rollup-5d1jnwi, r=matthiaskrgr cb9403f83a3 Rollup merge of #122088 - ChrisDenton:fixme, r=workingjubilee 3394c50e9b8 Rollup merge of #122072 - KonradHoeffner:patch-1, r=cuviper 05207f6b433 Rollup merge of #122091 - ChrisDenton:comment, r=RalfJung d80ad978bc1 Rollup merge of #122074 - KonradHoeffner:patch-2, r=jhpratt a30a91b5cfb Rollup merge of #113518 - jyn514:streaming-failures, r=cuviper 51a1133a7ff Document and test minimal stack size on Windows d27c01f2353 Add #[inline] to BTreeMap::new constructor d4913017e3a Dynamically size sigaltstk in std d8e07b01447 fix `close_read_wakes_up` test efbbf83abdd Note why we're using a new thread in a test 81aa0c5d7d0 Remove unnecessary fixme 4f885c0677e Be stricter with `copy_file_range` probe results 6e15e263bbf Auto merge of #121956 - ChrisDenton:srwlock, r=joboet a49271f6781 Less syscalls for the `copy_file_range` probe ff0ba4f9774 add missing PartialOrd impl doc for array bdb86b1e548 Refer to "slice" instead of "vector" in Ord and PartialOrd trait impl of slice 310c9d3db6e unix time module now return result 6e253074d96 Optimize write with as_const_str for shorter code cd9f85f04e4 Rollup merge of #122018 - RalfJung:box-custom-alloc, r=oli-obk 6f57062fd38 Rollup merge of #122016 - RalfJung:will_wake, r=dtolnay d308300cf85 Rollup merge of #121894 - RalfJung:const_eval_select, r=oli-obk 42ab8454dc2 Rollup merge of #121065 - CAD97:display-i18n, r=cuviper c6857bc8282 Add `Waitable` trait 469e90ae33c Implement MaybeUninit::fill{,_with,_from} 7b236d8e48e Auto merge of #121428 - okaneco:ipaddr_parse, r=cuviper 07a9a698ec2 only set noalias on Box with the global allocator a649c9c07de Auto merge of #121138 - Swatinem:grapheme-extend-ascii, r=cuviper de68f1af2c0 will_wake tests fail on Miri and that is expected a64376364c0 Auto merge of #122012 - matthiaskrgr:rollup-bzqjj2n, r=matthiaskrgr 9280cad9cf6 Rollup merge of #121826 - estebank:e0277-root-obligation-2, r=oli-obk 705e7d40bf0 Rollup merge of #121287 - zachs18:rc-into-raw-must-use, r=cuviper 4e1ece841fd Rollup merge of #121262 - 20jasper:add-vector-time-complexity, r=cuviper aed0f4539e0 Rollup merge of #121213 - Takashiidobe:takashi/example-for-rc-into-inner, r=cuviper feeefceec3e Auto merge of #121001 - nyurik:optimize-core-fmt, r=cuviper 3d0360b6f90 libtest: Print the names of failed tests eagerly e3f4a0eca11 doc wording improvements 3a422e78591 Explain use of display adapters af688c2a40a Windows: Implement mutex using futex a0c35c2c07c Auto merge of #120675 - oli-obk:intrinsics3.0, r=pnkfelix 61213d1e736 Add benches for `net` parsing 3828c9b4abe net: Add branch to Parser::read_number for parsing without checked arithmetic e32977fbb46 std::threads: revisit stack address calculation on netbsd. 995caf1fb52 Rollup merge of #121977 - Lee-Janggun:master, r=WaffleLapkin 704a4af3248 Rollup merge of #121968 - roblabla:fix-win7, r=jhpratt b824e34525c Rollup merge of #121939 - jonaspleyer:patch-typo-core-From-descr, r=workingjubilee ede7bfe9ce9 Rollup merge of #121732 - Voultapher:improve-assert_matches-documentation, r=cuviper 6c4ca4700ae Rollup merge of #120976 - matthiaskrgr:constify_TL_statics, r=lcnr 85c5da58cef Add a scheme for moving away from `extern "rust-intrinsic"` entirely 04f390b6823 Fix comment in Atomic{Ptr,Bool}::as_ptr. ee5a2cb5736 include feedback from workingjubilee e64346b12e5 Don't run test_get_os_named_thread on win7 6c212fc111c Rollup merge of #121935 - RalfJung:ptr-without-prov, r=scottmcm 252d08605c0 Be more lax in `.into_iter()` suggestion when encountering `Iterator` methods on non-`Iterator` 750149553b4 Use root obligation on E0277 for some cases 5deb016f0e7 Update library/core/src/sync/atomic.rs 90d36cc93f1 Update library/core/src/sync/atomic.rs 6279d103eb7 Use "size and alignment" rather than layout ab9bafb8ddd Document AtomicPtr bit validity 2e596b3f806 Clarify bit validity for AtomicBool 95a72681530 Clarify atomic bit validity ae21c42e505 std::rand: enable getrandom for dragonflybsd too. 3ed31cad520 Apply suggestions from code review 43c755442ff Small enhancement to description of From trait e9c04879d50 Fix quadratic behavior of repeated vectored writes 3c9b142c5e7 library/ptr: mention that ptr::without_provenance is equivalent to deriving from the null ptr 3e323f24c8a Add missing get_name for wasm::thread. 0c3951530b6 Auto merge of #121856 - ChrisDenton:abort, r=joboet 5818e9efe52 Auto merge of #121914 - Nadrieril:rollup-ol98ncg, r=Nadrieril ada8e9119ae Rollup merge of #121622 - dtolnay:wake, r=cuviper 92b88f81ba0 Cleanup windows abort_internal 720126f3be3 typo 28bab1d30e1 Rollup merge of #121888 - cppcoffee:style, r=Nilstrieb 93828eff6e1 Rollup merge of #121759 - RalfJung:addr_of, r=the8472 8ea1d321ba5 Rollup merge of #121758 - joboet:move_pal_thread_local, r=ChrisDenton f1f37876acc Rollup merge of #121666 - ChrisDenton:thread-name, r=cuviper 48aae0d71b3 const_eval_select: make it safe but be careful with what we expose on stable for now 39e4ccd841b Apply review comments 79991697acc attempt to further clarify addr_of docs e523a45069f Rollup merge of #121861 - tbu-:pr_floating_point_exact_examples, r=workingjubilee 09e9106f7cc Rollup merge of #121847 - shamatar:btreemap_fix_implicits, r=cuviper 208170c0b99 Rollup merge of #121835 - nnethercote:mv-HandleStore, r=bjorn3 ff1969107f5 Rollup merge of #109263 - squell:master, r=cuviper 9eb8804733d style library/core/src/error.rs d49f0898679 Rollup merge of #121730 - ecnelises:aix_pgo, r=wesleywiser 3f229f52f34 Rollup merge of #121634 - RavuAlHemio:slice-prefix-suffix-docs, r=cuviper d576b78406d Add `get_name` placeholder to other targets e952cd52ca0 Move capacity_overflow function to make ui tests change less 2f6e11fd242 try_with_capacity for Vec, VecDeque, String 4a047a7dea2 try_with_capacity for RawVec 20120366f1c Use the guaranteed precision of a couple of float functions in docs 6201e09b6cd Rollup merge of #121850 - reitermarkus:generic-nonzero-unsafe-trait, r=Nilstrieb dc6c0f8bb50 Rollup merge of #121736 - HTGAzureX1212:HTGAzureX1212/remove-mutex-unlock, r=jhpratt a7230fa667f Make `ZeroablePrimitive` trait unsafe. b92d36cdf72 remove hidden use of Global 793c9211399 revise interface to read directory entries cf820990815 Extending filesystem support for hermit-os 6107f2a550f Move `HandleStore` into `server.rs`. 540439d1eda Auto merge of #114016 - krtab:delete_sys_memchr, r=workingjubilee 33602997424 Rollup merge of #121809 - tgross35:suggest-path-split-fixup, r=Amanieu 6a74c6dab4e Rollup merge of #121753 - mu001999:core/add_cfg, r=cuviper 7d4f2a27589 Rollup merge of #121681 - jswrenn:nix-visibility-analysis, r=compiler-errors 40777fa6493 Remove doc aliases to PATH 5c2f7b31e48 Rollup merge of #121596 - ChrisDenton:tls, r=joboet a5cfbd1bb55 Forbid implementing `Freeze` even if the trait is stabilized c2beb54f5a5 Expose `Freeze` trait again a1a3ea63469 Rollup merge of #121793 - tbu-:pr_floating_point_32, r=Amanieu 792de42c0b3 Rollup merge of #121765 - hermit-os:errno, r=ChrisDenton d91d863a543 Rollup merge of #118217 - tbu-:pr_floating_point, r=Amanieu 75a75923ab8 Document which methods on `f32` are precise a7c2c1b6864 Document the precision of `f64` methods cec938ca17d Rollup merge of #121778 - ibraheemdev:patch-19, r=RalfJung e8449fa1cd4 Rollup merge of #121768 - ecton:condvar-unwindsafe, r=m-ou-se c9fadda2d72 Rollup merge of #120291 - pitaj:string-sliceindex, r=Amanieu 2e21b9ea5f0 Rollup merge of #119748 - tgross35:suggest-path-split, r=Amanieu 3c9296d1855 Drop link to matches macro and link matches macro to assert_matches. 68d2a309511 fix typos 7d8931f30e8 document potential memory leak in unbounded channel f6ba67e69fe Add proper cfg 35a333ec258 Rollup merge of #110543 - joboet:reentrant_lock, r=m-ou-se ee2526deeb3 Implement unwind safety for Condvar ffa4e9dd395 add platform-specific function to get the error number for HermitOS 1bde539b7c3 std: move thread local implementation to `sys` 3b3924f5770 Rollup merge of #121691 - janstarke:handle-missing-creation-time-as-unsupported, r=cuviper 519148897cb Rollup merge of #120051 - riverbl:os-str-display, r=m-ou-se c587b920e41 remove Mutex::unlock 7fce49983d4 Improve assert_matches! documentation c63a505093c Add profiling support to AIX 166be9ebcff Implement junction_point 84e78cac524 Auto merge of #119616 - rylev:wasm32-wasi-preview2, r=petrochenkov,m-ou-se 6691cd9b0c8 handle unavailable creation time as `io::ErrorKind::Unsupported` 5323ab5464a have `String` use `SliceIndex` impls from `str` 6dec65e357e safe transmute: revise safety analysis 201b7d43f34 Auto merge of #119636 - devnexen:linux_tcp_defer_accept, r=m-ou-se f7b46c43fff Rename wasm32-wasi-preview2 to wasm32-wasip2 47494c0448e Add the wasm32-wasi-preview2 target 03f63dde1fe Test getting the OS thread name 5d47b9a03b0 Use the OS thread name by default for the current thread 87d4b659320 intrinsics.rs: add some notes on unwinding 15923fd84b8 Stabilize the `#[diagnostic]` namespace and `#[diagnostic::on_unimplemented]` attribute 63df00e987a Generate original vtable and clone's vtable in the same CGU fb367e8fc85 Auto merge of #121655 - matthiaskrgr:rollup-qpx3kks, r=matthiaskrgr 41dbcff63ca Rollup merge of #121648 - jieyouxu:from-into-raw-parts-docs, r=Nilstrieb 9b644c54346 Rollup merge of #121598 - RalfJung:catch_unwind, r=oli-obk 74eb629b925 Auto merge of #121516 - RalfJung:platform-intrinsics-begone, r=oli-obk 50528218456 change std::process to drop supplementary groups based on CAP_SETGID 3fd6be06146 Document args returned from `String::into_raw_parts` 9366273ee1c Document args returned from `Vec::into_raw_parts{,_with_alloc}` 0b02c1e9b5a Rearrange `String::from_raw_parts` doc argument order to match code argument order b2608785c49 Rearrange `Vec::from_raw_parts{,_in}` doc argument order to match code argument order a5323fa34a7 fix race between block initialization and receiver disconnection 04ce65a6e76 Don't codegen wasm.throw unless with -Zbuild-std bab57af4c7a Remove _tls_used trickery unless needed ce4e820baa6 Clarify behavior of slice prefix/suffix operations in case of equality 9dbd6fa49cd Use volatile to make `p_thread_callback` used 4096b14cf3e Win10: Use GetSystemTimePreciseAsFileTime directly fe78547e7c3 miri: rename miri_start_panic → miri_start_unwind acb75f72bd2 rename 'try' intrinsic to 'catch_unwind' 19b365cb049 Fill in Read::read_buf for &Stdin e5d9fa825ff Fix stable feature name and stabilization version of Read for &Stdin feae9266265 Auto merge of #121317 - ChrisDenton:win10-sync, r=Mark-Simulacrum 1078f8d5895 Add Waker::will_wake tests 3cbe1cca7ac Auto merge of #120393 - Urgau:rfc3373-non-local-defs, r=WaffleLapkin a530abc9c7b Auto merge of #121591 - matthiaskrgr:rollup-8wfhh3v, r=matthiaskrgr 2ea3fe084d8 Rollup merge of #121513 - nshyrei:fix_tests_module, r=cuviper aa6d7f36480 Rollup merge of #119590 - ChrisDenton:cfg-target-abi, r=Nilstrieb 67678ebe968 Fix Hash impl e8c49b4eb46 Windows: Use ProcessPrng for random keys ba32bc1b427 Make push docs more vague 5b94c10603e remove platform-intrinsics ABI; make SIMD intrinsics be regular intrinsics a153a28fc92 Auto merge of #117107 - zachs18:mapped-mutex-guard, r=Amanieu b886e8dcbf0 Auto merge of #121114 - Nilstrieb:no-inline!, r=saethlin 094e51d5ca5 Auto merge of #121569 - matthiaskrgr:rollup-awglrax, r=matthiaskrgr 52872ff94fa Rollup merge of #121556 - GrigorenkoPV:addr_of, r=Nilstrieb 2a505f77ade Rollup merge of #121551 - nbdd0121:ffi_unwind, r=RalfJung b906a59cf59 Rollup merge of #121530 - wgslr:master, r=Mark-Simulacrum 5551e158abc Rollup merge of #121343 - Takashiidobe:takashi/examples-for-slice, r=Mark-Simulacrum 103b272be89 Stabilize `cfg_target_abi` 05a86413a3e Add `#[rustc_no_mir_inline]` for standard library UB checks d4356243e87 Forbid use of `extern "C-unwind"` inside standard library e3094ac0aa2 library: use `addr_of!` 68f392959b6 update stdarch 473ba17e238 Fix incorrect doc of ScopedJoinHandle::is_finished 02e777771e8 Auto merge of #119536 - Jules-Bertholet:const-barrier, r=dtolnay a18297c6f78 std: make `ReentrantLock` public a2f21fd20d0 Auto merge of #121303 - GrigorenkoPV:static_mut_refs, r=oli-obk,RalfJung fb5b1bfd414 Auto merge of #121514 - matthiaskrgr:rollup-5f0vhv7, r=matthiaskrgr 18dfc31163d Rollup merge of #121498 - flba-eb:make_timespec_capping_public, r=Nilstrieb d7c89ecb907 moved tests file 36d1174fedc Get rid of some `#[allow(static_mut_refs)]` 9c58f0ef4ed Auto merge of #121454 - reitermarkus:generic-nonzero-library, r=dtolnay f4f100ed696 Make timespec capping public to crate::sys e5b49e3c64c remove repetitive words e66a0172589 Auto merge of #120730 - estebank:confusable-api, r=oli-obk cf7219e88cd Use Itanium ABI for thrown exceptions 334c26de101 Unconditionally pass -wasm-enable-eh 288ff586111 std support for wasm32 panic=unwind 38a77fc16dd Add `flatmap`/`flat_map` -> `and_then` suggestions 164ff60051f On type error of method call arguments, look at confusables for suggestion 260a463b998 Add `rustc_confusables` annotations to some stdlib APIs db029b4c91e Rollup merge of #121439 - jrudolph:patch-1, r=bjorn3 9252783f914 Fix example. f99d57e7433 Use generic `NonZero` everywhere else. 9d5f7fac2e3 Use generic `NonZero` everywhere in `alloc`. 40f70478a18 Use generic `NonZero` everywhere in `std`. f4a3548962c Use generic `NonZero` everywhere in `core`. f9fc3d6415c Auto merge of #121309 - Nilstrieb:inline-all-the-fallbacks, r=oli-obk e3680244f6d Fix typo in metadata.rs doc comment fc69357999a Add std::ffi::c_str modules fb510e5e16b Auto merge of #117174 - Ayush1325:uefi-stdio-improve, r=workingjubilee 8af2eaec49c Auto merge of #121223 - RalfJung:simd-intrinsics, r=Amanieu 55d3303b70b Auto merge of #118634 - Jules-Bertholet:box-allocator-static, r=Amanieu df48817107e Always use WaitOnAddress on Win10+ 6c272962e4e os::net: expanding TcpStreamExt for Linux with `tcp_deferaccept`. 2f7898d1df6 remove simd_reduce_{min,max}_nanless 13bbd093612 rename ptr::invalid -> ptr::without_provenance 9e4871dff4c Remove unnecessary map_err 99a7ce86e03 TryReserveError to ErrorKind::OutOfMemory 70e6bc4ff74 make simd_reduce_{mul,add}_unordered use only the 'reassoc' flag, not all fast-math flags d88bf91ba5a intrinsics::simd: add missing functions da955c86fa8 Auto merge of #121383 - Dylan-DPC:rollup-735p4u4, r=Dylan-DPC 346cac52402 Auto merge of #120718 - saethlin:reasonable-fast-math, r=nnethercote bbe6e562dd9 Rollup merge of #121361 - pitaj:diag_items-legacy_numeric_constants, r=Nilstrieb e3618e1b7f4 Stabilize `LazyCell` and `LazyLock` (`lazy_cell`) 496ae2162ad Delete architecture-specific memchr code in std::sys 70bdcfeaab3 diagnostic items for legacy numeric modules 36dda9bb241 Add extra detail to field comment f4aeb69843b Reduce alignment of TypeId to u64 alignment 8764f670b8e Rollup merge of #121352 - malobre:patch-1, r=Nilstrieb 8649be79ff9 Rollup merge of #121277 - reitermarkus:generic-nonzero-convert-num, r=dtolnay eafa22a830f Rollup merge of #119203 - farnoy:simd-masked-intrinsic-docfix, r=RalfJung 391c15d1474 Add "algebraic" versions of the fast-math intrinsics 4383065d839 docs: add missing "the" to `str::strip_prefix` doc 50530c1309b Auto merge of #121345 - Nilstrieb:rollup-reb0xge, r=Nilstrieb 96db61e799b Add examples for some methods on slices 1655efdcd7e Rollup merge of #121302 - GrigorenkoPV:refmutl, r=bjorn3 6727224c48b Rollup merge of #121241 - reitermarkus:generic-nonzero-traits, r=dtolnay 2c9f0a468db Rollup merge of #121196 - Nilstrieb:the-clever-solution, r=saethlin 1ed97c5bb6c Auto merge of #120863 - saethlin:slice-get-checked, r=the8472 6054a1edf47 fix doc link c7799911e15 Rollup merge of #121311 - Nilstrieb:is-it-overlapping, r=saethlin 21c1c994e15 Rollup merge of #121310 - GrigorenkoPV:doc-smallfix, r=Nilstrieb 1afb0c4b3fa A much simpler version of write 2e36f990f88 remove const 078d5f7d381 add safety text 6a3164d30f4 Fix inlining issue for non-const case 5400a16839b Use intrinsic 703f82d9664 perf: improve write_fmt to handle simple strings ab38c8d2ddb Add more inline(always) to fix opt-level=z test on wasm32 3151afce76e Convert debug_assert_nounwind to intrinsics::debug_assertions fd605bd2cb8 Auto merge of #121185 - GuillaumeGomez:update-stdarch, r=Amanieu c726f0261f4 Make `is_nonoverlapping` `#[inline]` 6242c3b7452 Make intrinsic fallback bodies cross-crate inlineable bb3cc5ad796 Remove an old hack for rustdoc 29d19dcde20 Auto merge of #121177 - joboet:move_pal_locks, r=ChrisDenton 54f932b3a17 Always inline check in `assert_unsafe_precondition` with cfg(debug_assertions) 00056805e96 Remove `RefMutL` hack in `proc_macro::bridge` 75c2b7c8ca6 Rollup merge of #121272 - pitaj:diag_items-legacy_numeric_constants, r=Nilstrieb 85829818ad7 Rollup merge of #121041 - Nilstrieb:into-the-future-of-2024, r=Mark-Simulacrum a53581814d8 Rollup merge of #119808 - GnomedDev:encode-charsearcher-size-in-type, r=Mark-Simulacrum 15e4fd7bf48 Update stdarch submodule 474122f9cd5 Refactor trait implementations in `core::convert::num`. 05a691253da Auto merge of #105917 - a1phyr:read_chain_more_impls, r=workingjubilee 4461b4c2a00 Clarify/add `must_use` message for Rc/Arc/Weak::into_raw. 5ee2b188aa5 Auto merge of #121269 - calebzulawski:sync-portable-simd-2024-02-18, r=Mark-Simulacrum b0c745d9c1a Fix error in push docs 62dbc6cc30b Auto merge of #121101 - GnomedDev:dyn-small-c-string, r=Nilstrieb 4bf3700810e Add `Future` and `IntoFuture` to the 2024 prelude ddb1261778d diagnostic items for legacy numeric constants 6875a8c7f62 Dyn erase at call site 055157ab5d6 Add some comments to prevent regression ac04eb38e5a Reduce monomorphisation bloat in small_c_string 78d1702c900 Rollup merge of #121266 - SabrinaJewson:easy-syscall-aliases, r=Mark-Simulacrum 7e0d1c9500d Rollup merge of #121224 - hi-rustin:rustin-patch-unit-binding, r=Mark-Simulacrum 5015537e812 Rollup merge of #118569 - blyxxyz:platform-os-str-slice, r=Mark-Simulacrum 412bd0f7661 Merge commit '649110751ef4f27440d7cc711b3e07d11bf02d4a' into sync-portable-simd-2024-02-18 a54c3a448e8 Add uncontroversial syscall doc aliases to std docs 40adbedd027 Auto merge of #117772 - surechen:for_117448, r=petrochenkov 31cfe1a7125 fix typo in push documentation bfca794c2cb intradoc link for vec 4421503cf31 time complexity for insert 65d3a0d3377 time complexity for pop 7d159dceab8 time complexity for push_within_capacity a0948c7fed2 time complexity for push 0547ac207d1 By tracking import use types to check whether it is scope uses or the other situations like module-relative uses, we can do more accurate redundant import checking. 943ce5acd41 Auto merge of #121034 - obeis:improve-static-mut-ref, r=RalfJung fc226824d6f Improve wording of static_mut_ref 223255ec596 Auto merge of #118264 - lukas-code:optimized-draining, r=the8472 81c22089039 Implement `NonZero` traits generically. f85fc18c62d Auto merge of #121204 - cuviper:flatten-one-shot, r=the8472 ddbf53935ae Rollup merge of #121149 - SebastianJL:patch-1, r=Mark-Simulacrum ee547e71312 Rollup merge of #120952 - saethlin:vec-into-iter, r=the8472 969378fa8de Auto merge of #121232 - RalfJung:miri, r=RalfJung 2fe436beef7 Allow newly added non_local_definitions in std 7bb73448859 Rollup merge of #121192 - oli-obk:intrinsics2.0, r=WaffleLapkin a6caf1e2207 Rollup merge of #121187 - Takashiidobe:takashi/examples-for-quickselect, r=Nilstrieb 4a2507e05b7 Rollup merge of #119032 - smmalis37:patch-1, r=ChrisDenton 77218087488 Remove unnecessary unit binding 9de0c31f453 Merge from rustc 67162380ebe Auto merge of #120563 - reitermarkus:generic-nonzero-get, r=dtolnay ffb89bb20c6 Add an example to demonstrate how Rc::into_inner works 069187ef275 Auto merge of #120741 - a1phyr:safe_buffer_advance, r=m-ou-se 189fe462230 Clarify the flatten specialization comment 542395376c6 Remove cfg_attr 12fc48bf891 Use a hardcoded constant instead of calling OpenProcessToken. 3fe504b0b5b Give the (`un`)`likely` intrinsics fallback bodies 70b72da0948 Give the `assume` intrinsic a fallback body a40bbb29db6 Specialize flattening iterators with only one inner item 57bcd088222 Don't use mem::zeroed in vec::IntoIter 4830e6fc06d Add examples to document the return type of `select_nth_unstable`, `select_nth_unstable_by`, and `select_nth_unstable_by_key`. f3985a9509e Auto merge of #116385 - kornelski:maybe-rename, r=Amanieu 8d29abfc57f address review comments a0877d6310a outline large copies 7174001a399 reduce branchiness afce4017fbc reduce amount of math ca99f5c079f simplify codegen for trivially droppable types 5934c35393e Auto merge of #120538 - kornelski:read-not-exact, r=m-ou-se 5e0eb86bbeb std: move locks to `sys` on platforms without threads 602a789b058 std: move locks to `sys` on xous f89a575dbff std: move locks to `sys` on Windows 543a986cb1c std: move locks to `sys` on UNIX and other futex platforms b106494a6c2 std: move locks to `sys` on teeos ba2a95b839f std: move locks to `sys` on SGX e7f7f0ca087 std: move locks to `sys` on µITRON c6061317f33 Auto merge of #120500 - oli-obk:intrinsics2.0, r=WaffleLapkin 00ca8d43eb6 Auto merge of #120486 - reitermarkus:use-generic-nonzero, r=dtolnay 2ef55553671 Merge from rustc 3ea06b7489f Auto merge of #120889 - Ayush1325:uefi-instant, r=joshtriplett 6dc516b26c3 Rollup merge of #121155 - tspiteri:strict-doc-overflow, r=Nilstrieb 58938603961 Rollup merge of #120971 - PizzasBear:patch-1, r=Nilstrieb 2ba1c2c76aa Rollup merge of #120777 - Marcondiro:unicode15-1, r=Manishearth 65ca2ed6dd2 doc: panicking division by zero examples for unsigned strict div ops 05dca8bb4b7 doc: add note before panicking examples for strict_overflow_ops 597a9cff98b Auto merge of #121142 - GuillaumeGomez:rollup-5qmksjw, r=GuillaumeGomez 10e7998b746 Fix typo in VecDeque::handle_capacity_increase() doc comment. 559ebd94b02 Add slice::try_range ff7448bcecc Auto merge of #119863 - tmiasko:will-wake, r=m-ou-se e9f2e92465b Rollup merge of #121120 - nnethercote:LitKind-Err-guar, r=fmease a7618cd6c2e Rollup merge of #120672 - devnexen:update_thread_stack_guardpages_fbsd, r=m-ou-se 1a31ef4feb5 Rollup merge of #120505 - Amanieu:fix-btreemap-cursor-remove, r=m-ou-se 1fc66f043cc Rollup merge of #120449 - udoprog:document-unsized-rc-arc-from-raw, r=m-ou-se 9640b95498a Add ASCII fast-path for `char::is_grapheme_extended` 56774bf135b Rollup merge of #121098 - ShoyuVanilla:thread-local-unnecessary-else, r=Nilstrieb 5cf21cfae17 Rollup merge of #121082 - peterjoel:atomic-docs, r=cuviper 771641f81e9 Rollup merge of #118749 - ChrisDenton:winsys, r=cuviper 73b72d4bfda Rollup merge of #111106 - Stargateur:doc/format_args, r=m-ou-se ad2899bc107 Replace `NonZero::<_>::new` with `NonZero::new`. 4a44f1e579d Use generic `NonZero` internally. 85c1eaad85c Add `ErrorGuaranteed` to `ast::LitKind::Err`, `token::LitKind::Err`. 76cbf5ed93a Clarified docs on non-atomic oprations on owned/mut refs to atomics eca76eead5b Merge from rustc 2ff6b832e97 Remove unnecessary else block from `thread_local!` expanded code f2c01e53d79 Auto merge of #121078 - oli-obk:rollup-p11zsav, r=oli-obk 200e9ad7991 Rollup merge of #121073 - IgorLaborieWefox:patch-1, r=workingjubilee f8c56db25db Rollup merge of #121024 - joseluis:feat-asciichar-default, r=scottmcm 282161e09e3 Rollup merge of #118890 - Amanieu:allocator-lifetime, r=Mark-Simulacrum c098088f1a3 Rollup merge of #118738 - devnexen:netbsd10_update, r=cuviper bd76524cfb8 Rollup merge of #116387 - kpreid:wake-doc, r=cuviper 2011cd6fbfb Auto merge of #100603 - tmandry:zst-guards, r=dtolnay ce8ed2d2398 Automatically sort windows_sys bindings b0b92676baf Add windows_sys readme 3477122590b Move windows_sys.lst to bindings.txt d68036c9189 Fix typos in `OneLock` doc e0dbf42a7ff Fix incorrect use of `compile_fail` 77f3ef71910 Add information about allocation lifetime to Allocator::allocate a2038fa64c6 implement `Default` for `AsciiChar` 8e673259240 Implement Instant for UEFI de9fc7fe984 Auto merge of #121003 - matthiaskrgr:rollup-u5wyztn, r=matthiaskrgr b56677b252e Rollup merge of #120986 - tshepang:extraneous, r=cuviper b19e32c4990 Rollup merge of #120967 - LeoDog896:master, r=cuviper ddc72e1e7ae Merge from rustc 49001a437f6 Auto merge of #120938 - Ayush1325:uefi-thread, r=joboet,Nilstrieb 7eb50f04a04 docs: use correct link, use secondary example ddbebe63f52 iterator.rs: remove "Basic usage" text 55c52cb51bc Support safe intrinsics with fallback bodies f36d87dadc4 Give const_deallocate a default body b199376aef6 Teach llvm backend how to fall back to default bodies 358ccd2d7ab Check signature of intrinsics with fallback bodies c214d211b66 Rollup merge of #120936 - ripytide:master, r=Amanieu 2eac88547e6 constify a couple thread_local statics 6ac97ffe3eb style: fmt a4bd86259ec Clarify the lifetimes of allocations returned by the `Allocator` trait a7d04ac750d Fix comment in core/src/str/validations.rs faa017ea3bb docs: mention round-to-even in precision formatting a6f56a6be4e Merge from rustc 6489cd111db Auto merge of #110211 - joboet:queue_lock, r=Amanieu da88115dad3 Implement intrinsics with fallback bodies 077a938122a Rollup merge of #120888 - saethlin:unsafe-precondition-cleanup, r=RalfJung 9772c8cbdfd Rollup merge of #120880 - RalfJung:vtable-fnptr-partialeq, r=cuviper 1dee4f0703f Rollup merge of #120740 - ChrisDenton:cmaths, r=Mark-Simulacrum 273cbe0a6c6 Rollup merge of #110483 - tleibert:thin-box-try-new, r=dtolnay 2dab4fe1903 std: use `stream_position` where applicable 2d8089fd28b add comparison warning to RawWakerVTable as well ae8ab173fb7 fix intra-doc links c5fa5f5b9b3 Implement sys/thread for UEFI c824bae5d16 Auto merge of #120903 - matthiaskrgr:rollup-tmsuzth, r=matthiaskrgr 37364b76f63 Cleanup around the new assert_unsafe_precondition 12927b7601e fix incorrect doctest 2c5fd001689 improve `btree_cursors` functions documentation 38f927cc3e8 add doc-comment to `unlock_queue` 6164ef31dba std: enabling new netbsd (10) calls. de9be0b99e8 Rollup merge of #120459 - rytheo:handle-conversion-docs, r=Mark-Simulacrum 63da73cd651 Rollup merge of #120307 - djc:duration-constructors, r=Mark-Simulacrum 5939135948f Rollup merge of #119449 - Nilstrieb:library-clippy, r=cuviper b5ddd40cf89 Rollup merge of #119242 - BenWiederhake:dev-from-nanos, r=joshtriplett 9d65388c50d Rollup merge of #118307 - scottmcm:tuple-eq-simpler, r=joshtriplett 8aa8816bbea Rollup merge of #117740 - majaha:format_docs, r=joshtriplett 55a0aba334c Remove the link. 5153cd99d02 URL-encode chars in fragment. dde2947c7a6 Additional doc links and explanation of `Wake`. 5f41af668e5 Merge from rustc efe11e054d7 Auto merge of #120232 - c272:json-buildstd, r=Mark-Simulacrum de102f72d7c Rollup merge of #119213 - RalfJung:simd_shuffle, r=workingjubilee 802deb3e43d add note on comparing vtables / function pointers f9480d77e35 Rollup merge of #120823 - LegionMammal978:clarify-atomic-align, r=RalfJung 455cfa8e7d3 Rollup merge of #120764 - Alfriadox:master, r=m-ou-se dbe63a59de6 various docs tweaks 4535c7af9fe simd_scatter: mention left-to-right order 5f8fae5b949 add more missing simd intrinsics ea7bfc0d1d4 simd intrinsics: add simd_shuffle_generic 01958263ffb Stabilize slice_split_at_unchecked d8a25ac87e4 Auto merge of #120712 - compiler-errors:async-closures-harmonize, r=oli-obk c096cf854a8 Merge from rustc f50bdd77d81 Change wording 7652ced9f9f Auto merge of #120852 - matthiaskrgr:rollup-01pr8gj, r=matthiaskrgr bba76b7d3ba std::thread update freebsd stack guard handling. b20ff7650a0 Rollup merge of #120815 - camsteffen:inspect-docs, r=m-ou-se 50d1b5628e4 Rollup merge of #120776 - joboet:move_pal_path, r=ChrisDenton 449e800010b Rollup merge of #120351 - Ayush1325:uefi-time, r=m-ou-se 27b95e7bf0e Auto merge of #120676 - Mark-Simulacrum:bootstrap-bump, r=clubby789 66ddaddcee9 address review comments 1e7a6246efa Bump Unicode to version 15.1.0, regenerate tables b68a1bd47cd be more explicit about why adding backlinks eagerly makes sense ced2940bfe6 Improve Option::inspect docs 5a55e5e274f Auto merge of #120843 - matthiaskrgr:rollup-med37z5, r=matthiaskrgr 7a96ce40569 format using latest rustfmt bf051060f8f inline some single-use functions, add documentation ec8ad20855d queue_rwlock: use a separate `QUEUE_LOCKED` bit to synchronize waiter queue updates 31cc1fe2d5c use exponential backoff in `lock_contended` 7aeed7a4efc immediately register writer node if threads are queued 44f42bfe7b5 avoid unnecessary `Thread` handle allocation a527814393d use braces to make operator precedence less ambiguous 615a5d55a8b adjust code documentation a8528d5a013 std: replace pthread `RwLock` with custom implementation inspired by usync febce64f09a Rollup merge of #120809 - reitermarkus:generic-nonzero-constructors, r=Nilstrieb 21e6157a7cb Rollup merge of #120308 - utkarshgupta137:duration-opt, r=m-ou-se 6933efa1b3e Auto merge of #120594 - saethlin:delayed-debug-asserts, r=oli-obk 1494bd6dd2a Auto merge of #120238 - joboet:always_confirm_lock_success, r=Mark-Simulacrum 3698d7ce2ca Clarify that atomic and regular integers can differ in alignment abf979d5394 Add and use Unique::as_non_null_ptr cc3a154a9f7 Make `NonZero::get` generic. d222df5945a Use `transmute_unchecked` in `NonZero::new`. 2f0f32810d7 Reduce use of NonNull::new_unchecked in library/ db2d62e9bed Remove a now-obviated debug_assert! 5a0b38ced67 Rewrite assert_unsafe_precondition around the new intrinsic c5824d799fd Add a new debug_assertions intrinsic 202122fbe78 Step all bootstrap cfgs forward be7b8d7c433 Bump version placeholders e35d1680876 std: move path into `sys` 5841aa3696b Auto merge of #120558 - oli-obk:missing_impl_item_ice, r=estebank 6cd7906a990 Fix whitespace issues that tidy caught 22060c6253e Add documentation on `str::starts_with` b92dc65359c Auto merge of #120521 - reitermarkus:generic-nonzero-constructors, r=dtolnay e65acec26a7 Auto merge of #120381 - fee1-dead-contrib:reconstify-add, r=compiler-errors e454a608818 Make `io::BorrowedCursor::advance` safe b6f07b6e6aa Make cmath.rs a single file 3e641b3ebaa Replace `transmute_copy` with `ptr::read`. 612bd5ba1d8 Don't use `assert_unsafe_precondition` twice. 74c2cb6d3e2 Auto merge of #120527 - GnomedDev:atomicu32-handle, r=petrochenkov 688dc23d16f Make `NonZero` constructors generic. 8f2da05f56d Simplify `impl_zeroable_primitive` macro. 5b94c449f49 Update tests df6a3523ab8 Auto merge of #117905 - RalfJung:no-const-mut, r=lcnr 4e0ec2d06ee Harmonize blanket implementations for AsyncFn* traits f7e2d7d53b2 Auto merge of #120361 - compiler-errors:async-closures, r=oli-obk 84af84215e4 Auto merge of #120326 - tmandry:abort-in-tests, r=cuviper 48f609f2c48 Bless tests, add comments 83230098192 Teach typeck/borrowck/solvers how to deal with async closures 96dca854da7 revert stabilization of const_intrinsic_copy 144c899ff7a Auto merge of #117372 - Amanieu:stdarch_update, r=Mark-Simulacrum 41c394da876 Remove some invalid cfg(doc) code 67f764a08af Rollup merge of #120657 - mu001999:clean, r=Nilstrieb 5b150013766 Rollup merge of #120384 - wackbyte:array-equality-generics, r=Mark-Simulacrum 92ba832c846 Rollup merge of #118960 - tvallotton:local_waker, r=Mark-Simulacrum 65cef28714a Rollup merge of #115386 - RalfJung:partial-eq-chain, r=dtolnay e2c0cab8480 Rollup merge of #113833 - WiktorPrzetacznik:master, r=dtolnay b217ab650ec Rollup merge of #120607 - conradludgate:fix-120603, r=dtolnay 6bea1135e03 Rollup merge of #120572 - pheki:update-libc, r=Mark-Simulacrum d8bbe0c87b4 Rollup merge of #120458 - rytheo:cstr-conversion-doc, r=Mark-Simulacrum 7350e9ff337 Rollup merge of #119481 - romanows:fix-doc-select-nth-unstable, r=Mark-Simulacrum 52954384ccb Remove unused struct 87a36445a46 Auto merge of #120624 - matthiaskrgr:rollup-3gvcl20, r=matthiaskrgr 7b13aa8f5a6 Reconstify `Add` d63d44177b6 Rollup merge of #120528 - GnomedDev:atomicu8-backtrace-style, r=cuviper 59db7fc8390 Rollup merge of #120523 - a1phyr:improve_read_buf_exact, r=the8472 2714da2db85 add another test to make sure it still works with full reads 8617acdd368 fix #120603 by adding a check in default_read_buf 393be2c89f7 Docs for std::ptr::slice_from_raw_parts b451b5cb43c Update libc to 0.2.153 2a0afde1fe6 Revert unsound libcore changes of #119911 3e9a9c5da3c Make File::read_to_end less special a1d6b431147 Store SHOULD_CAPTURE as AtomicU8 886a216b03a Switch OwnedStore handle count to AtomicU32 0886272e725 Rollup merge of #120430 - devnexen:fix_tls_dtor_fbsd, r=cuviper f620e306e91 Rollup merge of #120355 - the8472:doc-vec-fromiter, r=cuviper b8176fd035e Improve `io::Read::read_buf_exact` error case ff6202bf0a2 Fix BTreeMap's Cursor::remove_{next,prev} ccee1422825 Rollup merge of #120485 - chenyukang:yukang-add-query-instability-check, r=michaelwoerister fd60d0af808 Rollup merge of #120445 - Nemo157:arc-plug, r=Mark-Simulacrum 7267e2a6ea9 Rollup merge of #120434 - fmease:revert-speeder, r=petrochenkov 90253f7c956 Rollup merge of #120295 - reitermarkus:remove-ffi-nonzero, r=dtolnay 25eb179c82f Rollup merge of #120452 - alexcrichton:update-windows-seek-write-docs, r=ChrisDenton 9f070a7b578 Rollup merge of #120424 - RalfJung:raw-ptr-meta, r=Nilstrieb bdfc6b5245a Rollup merge of #119991 - kornelski:endless-read, r=the8472 b80c5ee1c9d Auto merge of #117925 - kornelski:read-to-oom, r=Amanieu d3eac98b8e3 Disable conversions between portable_simd and stdarch on big-endian ARM 9bf1c8d0b3a add missing potential_query_instability for keys and values in hashmap 07aa8cade35 Add stdarch_wasm_atomic_wait feature in std cf32e1da759 Update feature names for new stdarch 333c1537bbe Update stdarch submodule 3fdc3b7109a Rollup merge of #120462 - mu001999:clean, r=Nilstrieb db73ba798f7 Rollup merge of #120373 - HTGAzureX1212:HTGAzureX1212/issue-120040, r=ChrisDenton 0c913f2a7f5 add extra check for invalid handle in ReadDir::next 3427b45a060 make modifications as per reviews c5bbd150c4c fix 73a289609c2 remove redundant call to Error::last_os_error e8b22ea4486 fix issue 120040 1d8f7d827cb Convert `Unix{Datagram,Stream}::{set_}passcred()` to per-OS traits 196cadc0fe7 Implement DoubleEnded and ExactSize for Take and Take 50a5dbe65f9 Add Read Impl for &Stdin REVERT: 78fc550584d Auto merge of #133247 - GuillaumeGomez:reduce-integer-display-impl, r=workingjubilee REVERT: db5c2c6a18f Rollup merge of #132982 - suaviloquence:2-doc-changed-alloc-methods, r=Mark-Simulacrum REVERT: 117ad4f17b0 Rollup merge of #132533 - SUPERCILEX:patch-4, r=Mark-Simulacrum REVERT: e2aa7c108dc fix `Allocator` method names in `alloc` free function docs REVERT: 6b141ee1007 Rollup merge of #133298 - n0toose:remove-dir-all-but-not-paths, r=Noratrieb REVERT: e3691db3d70 Rollup merge of #133260 - compiler-errors:deref, r=fee1-dead REVERT: 895f290b058 Rollup merge of #132730 - joboet:after_main_sync, r=Noratrieb REVERT: 6ffa4556f46 Rollup merge of #133389 - eduardosm:stabilize-const_float_methods, r=RalfJung REVERT: f4139353bf6 Rollup merge of #133301 - GuillaumeGomez:add-example-wrapping-neg, r=workingjubilee REVERT: 6112cfd51ba Auto merge of #132611 - compiler-errors:async-prelude, r=ibraheemdev REVERT: 23a5a0e1f54 Auto merge of #132597 - lukas-code:btree-plug-leak, r=jhpratt REVERT: f0b0942f402 Constify Deref and DerefMut REVERT: d05e8e8e9fb Auto merge of #133379 - jieyouxu:rollup-00jxo71, r=jieyouxu REVERT: 641c1ae3978 Stabilize `const_float_methods` REVERT: 256c54db000 Auto merge of #133377 - jieyouxu:rollup-n536hzq, r=jieyouxu REVERT: dff533fc1d3 Improve code by using `unsigned_abs` REVERT: a850f7c8760 Rollup merge of #133237 - fee1-dead-contrib:constadd, r=compiler-errors REVERT: 99741dd6dcb Rollup merge of #133332 - bjoernager:const-array-as-mut-slice, r=jhpratt REVERT: 9a152e2565f Rollup merge of #131505 - madsmtm:darwin_user_temp_dir, r=dtolnay REVERT: a12c8386f5b Auto merge of #132994 - clubby789:cc-bisect, r=Kobzol REVERT: 6548ad8c627 Auto merge of #133360 - compiler-errors:rollup-a2o38tq, r=compiler-errors REVERT: a4f797ed7de Rollup merge of #133264 - lolbinarycat:os-string-truncate, r=joboet REVERT: a9398015dc4 Auto merge of #132329 - compiler-errors:fn-and-destruct, r=lcnr REVERT: 30aa6db150e Add code example for `wrapping_neg` method for signed integers REVERT: bc77567dc6b Deduplicate checking drop terminator REVERT: 6f3ec5caf86 Gate const drop behind const_destruct feature, and fix const_precise_live_drops post-drop-elaboration check REVERT: fb6f0c2e982 Auto merge of #133339 - jieyouxu:rollup-gav0nvr, r=jieyouxu REVERT: c792ef3e01a Rollup merge of #133337 - ColinFinck:thread-scoped-fix-typo, r=joboet REVERT: cfed1c696dd Rollup merge of #133330 - RalfJung:close, r=the8472 REVERT: e26edf01cab Rollup merge of #133313 - thesummer:fix-arc4random, r=cuviper REVERT: 90a85ef0042 Rollup merge of #133288 - bjoernager:const-array-each-ref, r=jhpratt REVERT: 4e6f154dba6 Rollup merge of #133238 - heiher:loong-stdarch-rexport, r=Amanieu REVERT: 23a1b31cfa4 Auto merge of #130867 - michirakara:steps_between, r=dtolnay REVERT: 9693572a6e3 Fix typo in `std::thread::Scope::spawn` documentation. REVERT: b4a50679016 Mark '<[T; N]>::as_mut_slice' as 'const'; REVERT: b6b40efcac5 library: update comment around close() REVERT: 6ce7e79948e Don't try to use confstr in Miri REVERT: 40d6e2ca941 Auto merge of #129238 - umgefahren:stabilize-ipv6-unique-local, r=dtolnay REVERT: 276c0fc3fd1 distinguish overflow and unimplemented in Step::steps_between REVERT: 8be952bbbdf Use arc4random of libc for RTEMS target REVERT: 4583ddef0cd Mention that std::fs::remove_dir_all fails on files REVERT: 4f6ca37539a Mark and implement 'each_ref' and 'each_mut' in '[T; N]' as const; REVERT: ec220b6b368 constify `Add` REVERT: 3c558bf870d Rollup merge of #131736 - hoodmane:emscripten-wasm-bigint, r=workingjubilee REVERT: 38d4c11c3ff implement OsString::truncate REVERT: 4fd2c8db81e Rollup merge of #133226 - compiler-errors:opt-in-pointer-like, r=lcnr REVERT: 3f03a0f3fcd Rollup merge of #130800 - bjoernager:const-mut-cursor, r=joshtriplett REVERT: eea7e230c2b Rollup merge of #129838 - Ayush1325:uefi-process-args, r=joboet REVERT: 8b4995aad87 Make PointerLike opt-in as a trait REVERT: f74b38aa2b1 Reduce integer `Display` implementation size REVERT: 2f179d1a7c9 Stabilize const_pin_2 REVERT: b2dc297e863 re-export `is_loongarch_feature_detected` REVERT: e26c298e75c Rollup merge of #132732 - gavincrawford:as_ptr_attribute, r=Urgau REVERT: d6ee9dbe8b0 Rollup merge of #133183 - n0toose:improve-remove-dir-docs, r=joboet REVERT: 40735d31322 Rollup merge of #125405 - m-ou-se:thread-add-spawn-hook, r=WaffleLapkin REVERT: 6c20348f356 Rollup merge of #123947 - zopsicle:vec_deque-Iter-as_slices, r=Amanieu REVERT: 2089cb3188c Update doc comments for spawn hook. REVERT: c02090d6a3a Address review comments. REVERT: 79bffa90cfe Fix tracking issue. REVERT: 3eff64c78b0 Add tracking issue. REVERT: 15bac4f115e Use Send + Sync for spawn hooks. REVERT: a42af062212 Add thread Builder::no_hooks(). REVERT: 49ac15b192b Update thread spawn hooks. REVERT: 2cc4b2ef6d9 Use add_spawn_hook for libtest's output capturing. REVERT: 24a0765dd03 Add std::thread::add_spawn_hook. REVERT: 50ac72542be Correct comments concerning updated dangling pointer lint REVERT: cdf54869ec6 Auto merge of #133205 - matthiaskrgr:rollup-xhhhp5u, r=matthiaskrgr REVERT: 543667a49e3 Rollup merge of #133200 - RalfJung:miri-rwlock-test, r=tgross35 REVERT: 7430eb407e2 ignore an occasionally-failing test in Miri REVERT: 607b493008b Rollup merge of #133182 - RalfJung:const-panic-inline, r=tgross35 REVERT: e6cd122d981 Rollup merge of #132758 - nnethercote:improve-get_key_value-docs, r=cuviper REVERT: a3c95972a3b Mention std::fs::remove_dir_all in std::fs::remove_dir REVERT: bd5c1426568 Bump `stdarch` to the latest master REVERT: e84f865601d const_panic: inline in bootstrap builds to avoid f16/f128 crashes REVERT: 05fecb95df2 std: allow after-main use of synchronization primitives REVERT: c1beb25002a Auto merge of #133160 - jhpratt:rollup-wzj9q15, r=jhpratt REVERT: ce80c9f20de Rollup merge of #133145 - kornelski:static-mutex, r=traviscross REVERT: f385ac21fee Auto merge of #128219 - connortsui20:rwlock-downgrade, r=tgross35 REVERT: 86151abcc67 rename rustc_const_stable_intrinsic -> rustc_intrinsic_const_stable_indirect REVERT: a33f889e959 Improve `{BTreeMap,HashMap}::get_key_value` docs. REVERT: 15e6fc0a5db Document alternatives to `static mut` REVERT: 1cd1dd7c56f Auto merge of #120370 - x17jiri:likely_unlikely_fix, r=saethlin REVERT: e475f40115f Likely unlikely fix REVERT: ddcabfe85ff Rollup merge of #133126 - ohno418:fix-String-doc, r=jhpratt REVERT: e4eff6a5a78 Rollup merge of #133116 - RalfJung:const-null-ptr, r=dtolnay REVERT: 16e6d209ccb alloc: fix `String`'s doc REVERT: e4fb96229e0 clean up const stability around UB checks REVERT: ee78601c3ce stabilize const_ptr_is_null REVERT: 1e4a9ee22cd Rollup merge of #132449 - RalfJung:is_val_statically_known, r=compiler-errors REVERT: 1dfe94c308a Rollup merge of #131717 - tgross35:stabilize-const_atomic_from_ptr, r=RalfJung REVERT: 70326e8f708 reduce threads in downgrade test REVERT: d58e4f2d08c fix `DOWNGRADED` bit unpreserved REVERT: 5d683160ada fix memory ordering bug + bad test REVERT: 0604b8ffc1d add safety comments for queue implementation REVERT: 00255e627b7 add `downgrade` to `queue` implementation REVERT: 40256c63003 modify queue implementation documentation REVERT: f8041644f07 add `downgrade` to `futex` implementation REVERT: 572adedb6a0 add simple `downgrade` implementations REVERT: 48bcf09d8d7 add `downgrade` method onto `RwLockWriteGuard` REVERT: 5416aef6a86 add `RwLock` `downgrade` tests REVERT: 40109807569 Rollup merge of #133050 - tgross35:inline-f16-f128, r=saethlin REVERT: 2ee4159af2a Rollup merge of #133048 - cyrgani:ptr-doc-update, r=Amanieu REVERT: e1448dee6d0 Rollup merge of #133019 - sorairolake:add-missing-period-and-colon, r=tgross35 REVERT: b1d31d297f2 Rollup merge of #132984 - sunshowers:pipe2, r=tgross35 REVERT: 8cef1ef708e Rollup merge of #132977 - cberner:fix_solaris, r=tgross35 REVERT: daa9c433370 Rollup merge of #132790 - aDotInTheVoid:ioslice-asslice-rides-again, r=cuviper REVERT: cdb5ff5f6fe Pass `f16` and `f128` by value in `const_assert!` REVERT: 60ef4797595 use `&raw` in `{read, write}_unaligned` documentation REVERT: d2983fffb15 Auto merge of #132709 - programmerjake:optimize-charto_digit, r=joshtriplett REVERT: 918cc8d59c8 Rollup merge of #133027 - no1wudi:master, r=jhpratt REVERT: 25f55123bf2 Auto merge of #133026 - workingjubilee:rollup-q8ig6ah, r=workingjubilee REVERT: d8de2ccfc55 Fix a copy-paste issue in the NuttX raw type definition REVERT: c06bb349936 Rollup merge of #133008 - onur-ozkan:update-outdated-comment, r=jieyouxu REVERT: 8eaea39049a Rollup merge of #133004 - cuviper:unrecover-btree, r=ibraheemdev REVERT: 81a191a826e Rollup merge of #133003 - zachs18:clonetouninit-dyn-compat-u8, r=dtolnay REVERT: e3e5e358c71 Rollup merge of #132907 - BLANKatGITHUB:intrinsic, r=saethlin REVERT: f57853bc421 Rollup merge of #131304 - RalfJung:float-core, r=tgross35 REVERT: 7bc04367d32 Auto merge of #122770 - iximeow:ixi/int-formatting-optimization, r=workingjubilee REVERT: ce2e318c5d1 docs: Fix missing colon in methods for primitive types REVERT: 1870e9269bf docs: Fix missing period in methods for integer types REVERT: 64397743828 Auto merge of #133006 - matthiaskrgr:rollup-dz6oiq5, r=matthiaskrgr REVERT: 98dad0baf9a update outdated comment about test-float-parse REVERT: 520d4fdff72 Rollup merge of #126046 - davidzeng0:mixed_integer_ops_unsigned_sub, r=Amanieu REVERT: e3c425b74bb Auto merge of #132662 - RalfJung:const-panic-inlining, r=tgross35 REVERT: c4b77cf11ef Update core CloneToUninit tests REVERT: d4e21f55ec3 btree: simplify the backdoor between set and map REVERT: 5d61cf9a7ea Bump `cc` REVERT: 44f376ba0c7 Fix compilation error on Solaris due to flock usage REVERT: 75609d6d329 Auto merge of #132556 - clubby789:cargo-update, r=Mark-Simulacrum REVERT: 5ba28a4d89a Run `cargo update` and update licenses REVERT: 08200043034 const_panic: don't wrap it in a separate function REVERT: d30e2c0963b [illumos] use pipe2 to create anonymous pipes REVERT: 7e12686e222 Auto merge of #132883 - LaihoE:vectorized_is_sorted, r=thomcc REVERT: 02e32d70d61 Auto merge of #132972 - matthiaskrgr:rollup-456osr7, r=matthiaskrgr REVERT: 157eb1c94be Rollup merge of #132970 - tyilo:nonzero-u-div-ceil-issue, r=tgross35 REVERT: 03e52a50ac8 Rollup merge of #132966 - RalfJung:const_option_ext, r=jhpratt REVERT: 2f615a1c410 Rollup merge of #132948 - RalfJung:const_unicode_case_lookup, r=Noratrieb REVERT: f00e0913f63 Rollup merge of #132851 - chansuke:update-comment, r=thomcc REVERT: 656009854a3 Auto merge of #132870 - Noratrieb:inline-int-parsing, r=tgross35 REVERT: a0c0c40eafd Add tracking issue number to unsigned_nonzero_div_ceil feature REVERT: c2296662624 Make `CloneToUninit` dyn-compatible REVERT: 6ab50dd1c97 stabilize const_option_ext REVERT: 27fe6c7ca46 Rollup merge of #132541 - RalfJung:const-stable-extern-crate, r=compiler-errors REVERT: 7fafe990a8b stabilize const_unicode_case_lookup REVERT: c5ed62506ae Stabilize `Ipv6Addr::is_unique_local` and `Ipv6Addr::is_unicast_link_local` REVERT: e0452c9af5e adds new declaration to codegen REVERT: 33fa8701b27 Auto merge of #132943 - matthiaskrgr:rollup-164l3ej, r=matthiaskrgr REVERT: 7f12f02c6ec Rollup merge of #132914 - rcorre:cell-grammar, r=tgross35 REVERT: 300a2664117 Rollup merge of #132895 - scottmcm:generalize-nonnull-from-raw-parts, r=ibraheemdev REVERT: a461cf9310e remove no-longer-needed abs_private REVERT: 170e993a781 allow rustc_private feature in force-unstable-if-unmarked crates REVERT: 4a20245f4ad Rollup merge of #132929 - cuviper:check-alloc_zeroed, r=tgross35 REVERT: 992bbf7c46c Rollup merge of #132869 - lolbinarycat:library-fix-too_long_first_doc_paragraph, r=tgross35 REVERT: e3925fa3b42 Rollup merge of #132847 - RalfJung:addr-dont-expose, r=Mark-Simulacrum REVERT: 327a0d7814e Auto merge of #132919 - matthiaskrgr:rollup-ogghyvp, r=matthiaskrgr REVERT: 67c3c9f8bb7 Check for null in the `alloc_zeroed` example REVERT: 068537aeb72 new intrinsic declaration REVERT: b689951272e new intrinsic declaration REVERT: 16fa12ebd98 Rollup merge of #132144 - adetaylor:receiver-trait-itself, r=wesleywiser REVERT: 54f699d3ee9 Rollup merge of #120077 - SUPERCILEX:set-entry, r=Amanieu REVERT: e541a4f8204 Update dangling pointer tests REVERT: 7707584415a Tag relevant functions with #[rustc_as_ptr] attribute REVERT: b541c5aebc8 Auto merge of #132902 - matthiaskrgr:rollup-43qgg3t, r=matthiaskrgr REVERT: 2d676d49a6e Update grammar in std::cell docs. REVERT: 7325f33701c Emscripten: link with -sWASM_BIGINT REVERT: 1c482c93dbd Rollup merge of #130999 - cberner:flock_pr, r=joboet REVERT: 4dd22707d54 Auto merge of #127589 - notriddle:notriddle/search-sem-3, r=GuillaumeGomez REVERT: 0af64b63ced Generalize `NonNull::from_raw_parts` per ACP362 REVERT: 2fd9ac4a7ba vectorize slice::is_sorted REVERT: 737521c21f5 `#[inline]` integer parsing functions REVERT: b9be1ddefcb split up the first paragraph of doc comments for better summaries REVERT: f9063ff15cf Update the doc comment of `ASCII_CASE_MASK` REVERT: 57c7b80414a elem_offset / subslice_range: use addr() instead of 'as usize' REVERT: d19aa692d4e Rollup merge of #132136 - RalfJung:target-feature-abi-compat, r=Mark-Simulacrum REVERT: 6b0bd5a6630 honor rustc_const_stable_indirect in non-staged_api crate with -Zforce-unstable-if-unmarked REVERT: 070baf4fab5 Add as_slice/into_slice for IoSlice/IoSliceMut. REVERT: 978a5535d35 Rollup merge of #132778 - lolbinarycat:io-Error-into_inner-docs, r=cuviper REVERT: 6d54bfe5925 update io::Error::into_inner to acknowlage io::Error::other REVERT: 7c0a90c3ead Address review comments REVERT: ac66068ca8b Update library/std/src/sys/pal/windows/fs.rs REVERT: d90f8668e45 Auto merge of #132717 - RalfJung:rustc_safe_intrinsic, r=compiler-errors REVERT: f2bf9e65116 remove support for rustc_safe_intrinsic attribute; use rustc_intrinsic functions instead REVERT: 2391b4b2a0d Rollup merge of #132738 - cuviper:channel-heap-init, r=ibraheemdev REVERT: 086cfefa97e mark is_val_statically_known intrinsic as stably const-callable REVERT: dffc5e73119 Rollup merge of #132696 - fortanix:raoul/rte-235-fix_fmodl_missing_symbol_issue, r=tgross35 REVERT: f14fc562a82 Rollup merge of #132639 - RalfJung:intrinsics, r=workingjubilee,Amanieu REVERT: 6d63012a62e Initialize channel `Block`s directly on the heap REVERT: 7ff251b9793 core: move intrinsics.rs into intrinsics folder REVERT: 6244f4816fe Auto merge of #132714 - mati865:update-memchr, r=tgross35 REVERT: a2eaef75de6 Rollup merge of #132715 - tabokie:fix-lazy-lock-doc, r=Noratrieb REVERT: 6a77b2121f1 Rollup merge of #132665 - tyilo:nonzero-u-div-ceil, r=joboet REVERT: 79d2063e0b6 Separate f128 `%` operation to deal with missing `fmodl` symbol REVERT: 8022523cc73 Auto merge of #132705 - kornelski:inline-repeat, r=tgross35 REVERT: df9f5db19d7 fix lazylock comment REVERT: 7a82eb5b610 Auto merge of #131888 - ChrisDenton:deopt, r=ibraheemdev REVERT: 75b9ce3b0be unpin and update memchr REVERT: 4d1c7d9526a optimize char::to_digit and assert radix is at least 2 REVERT: 95bff3e6b5c Inline str::repeat REVERT: 52c2a459546 Rollup merge of #132617 - uellenberg:fix-rendered-doc, r=cuviper REVERT: 28f7e7bbbd9 Auto merge of #131721 - okaneco:const_eq_ignore_ascii_case, r=m-ou-se REVERT: 41b7e5f7705 Auto merge of #132500 - RalfJung:char-is-whitespace-const, r=jhpratt REVERT: 4ed08bd2262 Add new unstable feature `const_eq_ignore_ascii_case` REVERT: f4e9fe4ec00 Auto merge of #132664 - matthiaskrgr:rollup-i27nr7i, r=matthiaskrgr REVERT: afc66fe29e2 Change some code blocks to quotes in rendered std doc REVERT: 2e63cbdb695 Rollup merge of #131261 - clarfonthey:unsafe-cell-from-mut, r=m-ou-se REVERT: ab6f663ed6a Auto merge of #132661 - matthiaskrgr:rollup-npytbl6, r=matthiaskrgr REVERT: 8b165db1e5c Implement div_ceil for NonZero REVERT: 6bc1b1b449e Rollup merge of #132571 - RalfJung:const_eval_select_macro, r=oli-obk REVERT: c12f4d12055 Rollup merge of #132473 - ZhekaS:core_fmt_radix_no_panic, r=joboet REVERT: bbb927540c8 Rollup merge of #132153 - bjoernager:const-char-encode-utf16, r=dtolnay REVERT: 919de701b02 add const_eval_select macro to reduce redundancy REVERT: 538f5b4cd2b Rollup merge of #132609 - NotWearingPants:patch-1, r=Amanieu REVERT: 86c6f276b21 Rollup merge of #132606 - eduardosm:char-slice-str-pattern-doc, r=tgross35 REVERT: 4660d7ebef9 most const intrinsics don't need an explicit rustc_const_unstable any more REVERT: 8eb30fe4b09 add new rustc_const_stable_intrinsic attribute for const-stable intrinsics REVERT: 792d1646c7c convert all const-callable intrinsics into the new form (without extern block) REVERT: fad7d68d1c2 docs: fix grammar in doc comment at unix/process.rs REVERT: 92bb77993bd Improve example of `impl Pattern for &[char]` REVERT: 553bb181dad Add AsyncFn* to to the prelude in all editions REVERT: 2ae24bf3e15 Fixed typo, rebased REVERT: 47f60d7ad0d Updated SAFETY comment to address underflow REVERT: 581aa8d587f Replace checked slice indexing by unchecked to support panic-free code REVERT: c5a0f6c60aa Rollup merge of #132579 - RalfJung:rustc-std-workspace-crates, r=Amanieu REVERT: 9cdbf39ba56 btree: don't leak value if destructor of key panics REVERT: 4caff135a74 Stabilise 'const_char_encode_utf16'; REVERT: 84fae7ebfee Auto merge of #132586 - workingjubilee:rollup-qrmn49a, r=workingjubilee REVERT: 95b4127a6c8 update rustc-std-workspace crates REVERT: 082b98d885c Rollup merge of #132423 - RalfJung:const-eval-align-offset, r=dtolnay REVERT: 3b40634d007 Auto merge of #132434 - tgross35:f128-tests, r=workingjubilee REVERT: 5dea8b2e41f Enable `f128` tests on all non-buggy platforms 🎉 REVERT: 2bb8ea389a4 Auto merge of #132581 - workingjubilee:rollup-4wj318p, r=workingjubilee REVERT: 83bd286345b Update `compiler_builtins` to 0.1.138 and pin it REVERT: 699702f2a6c Rollup merge of #132563 - frectonz:master, r=Amanieu REVERT: 4390c35bcce Auto merge of #123723 - madsmtm:apple-std-os, r=dtolnay REVERT: 1e8ed9064ee Auto merge of #132479 - compiler-errors:fx-feat-yeet, r=fee1-dead REVERT: 9a3b7c0f20b Rename the FIXMEs, remove a few that dont matter anymore REVERT: ed4f110b101 Auto merge of #132542 - RalfJung:const_panic, r=tgross35 REVERT: d8bca01fc2b remove const-support for align_offset REVERT: 76b866c7156 Modify `NonZero` documentation to reference the underlying integer type REVERT: 9e579641927 Rollup merge of #132511 - RalfJung:const_arguments_as_str, r=dtolnay REVERT: bfeeb7450fd Rollup merge of #132503 - RalfJung:const-hash-map, r=Amanieu REVERT: a42fc213104 Rollup merge of #132499 - RalfJung:unicode_data.rs, r=tgross35 REVERT: 0278cab1fcc Rollup merge of #132393 - zedddie16:issue-131865-fix, r=tgross35 REVERT: 714115abfb6 Rollup merge of #131377 - rick-de-water:nonzero-exp, r=dtolnay REVERT: 9789c548b8c Rollup merge of #129329 - eduardosm:rc-from-mut-slice, r=dtolnay REVERT: ff9178b1a6a add const_panic macro to make it easier to fall back to non-formatting panic in const REVERT: 9ef483bbbb0 stabilize const_arguments_as_str REVERT: 4c6593fe8f8 Auto merge of #132458 - RalfJung:rustc-const-unstable, r=Amanieu REVERT: 81b20e0a3dd Rustdoc: added brief colon explanation REVERT: 73d9f4da9a9 Add Set entry API REVERT: e883a6074c2 Add BorrowedBuf::into_filled{,_mut} methods to allow returning buffer with original lifetime REVERT: 771d77c7cfa Rollup merge of #132495 - Houtamelo:remove_unintended_link, r=jieyouxu REVERT: d99f3cfc04b Rollup merge of #132493 - Houtamelo:doc_type-ref_html-tag, r=jieyouxu REVERT: e24475c97e0 Rollup merge of #132482 - lukas-code:stab-attrs, r=Noratrieb REVERT: 261c5b998ad remove const_hash feature leftovers REVERT: d515da6678b const_with_hasher test: actually construct a usable HashMap REVERT: 11dc6c388d9 make char::is_whitespace unstably const REVERT: 1a481fd9e01 unicode_data.rs: show command for generating file REVERT: 3a5b026c04a get rid of a whole bunch of unnecessary rustc_const_unstable attributes REVERT: 21e23b81a3a Rollup merge of #132398 - krtab:add_doc_link, r=Noratrieb REVERT: 64e247223a8 Remove unintended link REVERT: 166cea20be8 Fix type reference in documents which was being confused with html tags. REVERT: cab478ae96f fix some stability annotations REVERT: ecd55b1fa47 Rollup merge of #132459 - RalfJung:byte_sub_ptr, r=scottmcm REVERT: 3cd2636d62e Rollup merge of #132455 - RalfJung:const_alloc_layout, r=dtolnay REVERT: 8fdd6d4ceca Rollup merge of #132451 - RalfJung:less-rustc_allow_const_fn_unstable, r=tgross35 REVERT: 9f63901f152 Rollup merge of #132445 - RalfJung:const-unchecked-shifts, r=tgross35 REVERT: 2b0a6ddf113 Rollup merge of #132413 - lolbinarycat:offset_of_nested-docs, r=workingjubilee REVERT: 2e24b7fba4b remove no-longer-needed attribute REVERT: ffbcba08e7f add missing safety comments REVERT: 768d0cd7fe4 adjust test gating for f16/f128 REVERT: 6335056119f float types: move copysign, abs, signum to libcore REVERT: c80bb77d125 offset_from / sub_ptr docs: emphasize that pointers must be in the same allocation REVERT: 861009d737b feat(byte_sub_ptr): add ptr::byte_sub_ptr REVERT: f4e1fa3d8b7 make const_alloc_layout feature gate only about functions that are already stable REVERT: bf19bdab420 unchecked_shifts, unchecked_neg are safe-to-const-expose-on-stable, so we can get rid of a bunch of attributes REVERT: ebf7505acaa remove some unnecessary rustc_allow_const_fn_unstable REVERT: 36cfa4e5e34 Auto merge of #132206 - tgross35:update-builtins, r=wesleywiser REVERT: 4283f78c3d6 use semantic line break REVERT: a4b391601ce update offset_of! docs to reflect the stablization of nesting REVERT: f0634f0e84d Add intra-doc link in str::xxx_char_boundary REVERT: c353337b8d0 rustdoc-search: simplify rules for generics and type params REVERT: 5d892fb876e Remove do_not_const_check from Iterator methods REVERT: 93839e7405e Add intra-doc link in str::xxx_prefix REVERT: 8c0bdb3e115 Auto merge of #132238 - Urgau:midpoint-i64-hackers-impl, r=joboet REVERT: 9d10ab71105 Implement `From<&mut {slice}>` for `Box/Rc/Arc<{slice}>` REVERT: 9b9ea35b918 Auto merge of #132326 - matthiaskrgr:rollup-ngyw18g, r=matthiaskrgr REVERT: 94dd5c6224c Rollup merge of #132321 - betrusted-io:xous/fix-rustc_const_stable-attribute, r=joboet REVERT: eb2e4208c5c Auto merge of #132231 - lukas-code:rc-plug-leaks, r=tgross35 REVERT: ed1a265dec3 xous: sync: remove `rustc_const_stable` attribute REVERT: 6495896aefb Rollup merge of #132270 - yakiimoninja:fs-truncate-docs, r=Noratrieb REVERT: 057f9e91003 Rollup merge of #132233 - WaffleLapkin:box-module-split, r=workingjubilee REVERT: d0a99e723de Rollup merge of #131520 - zachs18:const-str-split, r=Noratrieb REVERT: e134006be99 Auto merge of #132277 - workingjubilee:rollup-5e6q6e4, r=workingjubilee REVERT: 34329c06529 Stabilize `const_atomic_from_ptr` REVERT: a1b88a08f16 Auto merge of #128985 - GrigorenkoPV:instantly-dangling-pointer, r=Urgau REVERT: 9318ae3e6ad Rc destructor: tweak inlining REVERT: 3a686cd946e Split `boxed.rs` into a few modules REVERT: 7be29e92b87 Rollup merge of #131441 - SpriteOvO:proc-macro-to-tokens-trait, r=dtolnay REVERT: d56ef5ac6af clarified std::fs truncate doc REVERT: b0248e22287 Auto merge of #132145 - RalfJung:stdarch, r=Amanieu REVERT: 191aa709931 clarified doc for `std::fs::OpenOptions.truncate()` REVERT: a5aa408646d New lint: `dangling_pointers_from_temporaries` REVERT: 8cdb783b8a6 Rollup merge of #131391 - ChaiTRex:isqrt, r=scottmcm,tgross35 REVERT: 4f4a6c641ca we can now enable the 'const stable fn must be stable' check REVERT: 79c45bee82c bump stdarch REVERT: 848fcd56c9e Auto merge of #132251 - jieyouxu:rollup-mtv9mpd, r=jieyouxu REVERT: e2122609dc1 Auto merge of #132200 - Mark-Simulacrum:strengthen-cross-lang, r=RalfJung REVERT: ac1ec5f65d3 Support `char::is_digit` in const contexts REVERT: b534a028f5a Use Hacker's Delight impl in `i64::midpoint` instead of wide `i128` impl REVERT: 28223bdba1d Rc/Arc: don't leak the allocation if drop panics REVERT: 5d8140df6fa add test for panicking drop in Box/Rc/Arc REVERT: cde6279ea2f Auto merge of #131284 - dingxiangfei2009:rename-smart-ptr-to-coerce-referent, r=compiler-errors REVERT: c6676830322 Auto merge of #132191 - Urgau:midpoint_signed_towards_zero, r=dtolnay REVERT: 80f0aa3a99b Add a new trait `proc_macro::ToTokens` REVERT: 3cfffb8c0ae Update compiler-builtins to 0.1.136 REVERT: 45d8393ddaf Auto merge of #131715 - tgross35:add-const_sockaddr_setters, r=Amanieu REVERT: ec7694203d1 Make clearer that guarantees in ABI compatibility are for Rust only REVERT: 139f6325aad Add test for all midpoint expectations REVERT: 4612afa48e0 Round negative signed integer towards zero in `iN::midpoint` REVERT: 06b5c8eae1b Rollup merge of #132019 - daboross:document-partialeq-oncelock, r=Mark-Simulacrum REVERT: 658e70932b5 Auto merge of #131349 - RalfJung:const-stability-checks, r=compiler-errors REVERT: db3b9fca1c0 Rollup merge of #132137 - RalfJung:behavior, r=Noratrieb REVERT: 6daffe4709d get rid of the internal unlikely macro REVERT: d2ff6a20074 Re-do recursive const stability checks REVERT: a2e1edf18f6 Arbitrary self types v2: (unused) Receiver trait REVERT: 295b932be95 library: consistently use American spelling for 'behavior' REVERT: 2d26681057c ABI compatibility: remove section on target features REVERT: 2348c065b0e Rollup merge of #131457 - kpreid:fnaddr, r=dtolnay REVERT: 2da7b7f12dc Auto merge of #132121 - workingjubilee:rollup-yrtn33e, r=workingjubilee REVERT: 5cf142bc64b Rollup merge of #132113 - LaihoE:pattern_as_utf8_default_impl, r=workingjubilee REVERT: 1f2f88e41ef Rollup merge of #132101 - youknowone:thread_local-gyneiene, r=tgross35 REVERT: 6c8134047be Rollup merge of #132048 - mustartt:aix-random-impl, r=workingjubilee REVERT: 980e5a2d181 Rollup merge of #131851 - sunshowers:musl-posix, r=workingjubilee REVERT: d25ee97a2b8 Avoid use imports in thread_local_inner! in statik REVERT: b4ea08d88cf Auto merge of #132116 - matthiaskrgr:rollup-3a0ia4r, r=matthiaskrgr REVERT: 0ae2951e1b0 Rollup merge of #131790 - nmathewson:doc_socketaddr_representation, r=tgross35 REVERT: 8baae66df74 Auto merge of #131985 - compiler-errors:const-pred, r=fee1-dead REVERT: 115a851440e provide default impl for as_utf8_pattern REVERT: a92f55cd463 Auto merge of #123550 - GnomedDev:remove-initial-arc, r=Noratrieb REVERT: c9460bfe499 Document textual format of SocketAddrV{4,6} REVERT: 78f4ed38d1d Remove associated type based effects logic REVERT: 21eb2c297f0 [musl] use posix_spawn if a directory change was requested REVERT: 03798ad0818 Rollup merge of #130225 - adetaylor:rename-old-receiver, r=wesleywiser REVERT: a45e03057ba Rollup merge of #132066 - tifv:ptr-docs-typo, r=Amanieu REVERT: 927edad8409 Rollup merge of #132065 - tifv:dangling-docs, r=Noratrieb REVERT: ded2a0afac4 Rollup merge of #132060 - joshtriplett:innermost-outermost, r=jieyouxu REVERT: e62b2cc663d Rollup merge of #132039 - a1phyr:vecdeque_read_exact, r=Noratrieb REVERT: 76e75ae973e Rollup merge of #130991 - LaihoE:vectorized_slice_contains, r=Noratrieb REVERT: 6799f8562be const fn str::split_at* REVERT: 887bcf653d8 const fn str::is_char_boundary REVERT: 01ed719bad8 vectorized SliceContains REVERT: 1bb8bdeeb98 s/SmartPointer/CoerceReferent/g REVERT: 843347f94b4 fix a typo in documentation of pointer::sub_ptr() REVERT: 10f64a79d36 fix documentation of ptr::dangling() function REVERT: 728a8d71d08 "innermost", "outermost", "leftmost", and "rightmost" don't need hyphens REVERT: 282790f75ad Specialize `read_exact` and `read_buf_exact` for `VecDeque` REVERT: 054b256111a Rollup merge of #132031 - slanterns:rc_default, r=ibraheemdev REVERT: 05b4955be28 Rollup merge of #131707 - clarfonthey:constify-core-tests, r=thomcc REVERT: b0fc9c793f3 Auto merge of #131929 - LaihoE:replace_default_capacity, r=joboet REVERT: 5c416b4572c AIX use /dev/urandom for impl REVERT: 09e26cb1460 better default capacity for str::replace REVERT: 3a5e669fcdb Rename Receiver -> LegacyReceiver REVERT: 224a60d32db refactor `Arc::default` REVERT: fe5101d2303 optimize `Rc::default` REVERT: 507193aaae8 Rollup merge of #131697 - ShE3py:rt-arg-lifetimes, r=Amanieu REVERT: 61fa53e24a6 Document PartialEq impl for OnceLock REVERT: 2e8dd5b1116 Rollup merge of #132003 - RalfJung:abi-compat-docs, r=traviscross REVERT: 7f91dbe9922 Rollup merge of #130350 - RalfJung:strict-provenance, r=dtolnay REVERT: 8499ec3da71 update ABI compatibility docs for new option-like rules REVERT: 6d2a4371f48 move strict provenance lints to new feature gate, remove old feature gates REVERT: 446117163a5 stabilize Strict Provenance and Exposed Provenance REVERT: e2b2c3aac1a fix docs REVERT: 20ed6b56971 replace FindFirstFileW with FindFirstFileExW and apply optimization REVERT: a065b8ecafd replace FindFirstFileW with FindFirstFileExW and regenerate bindings REVERT: 362aec6e09b Auto merge of #131948 - matthiaskrgr:rollup-c9rvzu6, r=matthiaskrgr REVERT: f1c99041c25 Support lock() and lock_shared() on async IO Files REVERT: 7628c4ff550 Rollup merge of #131921 - klensy:statx_all, r=ChrisDenton REVERT: affe042b2cf Rollup merge of #131772 - GnomedDev:remove-proc_macro-todo, r=petrochenkov REVERT: 5615efc263a Auto merge of #131907 - saethlin:update-compiler-builtins, r=tgross35 REVERT: b6b2903e331 Update `compiler-builtins` to 0.1.134 REVERT: b714f9d7b4f Rollup merge of #131919 - RalfJung:zero-sized-accesses, r=jhpratt REVERT: fb670790503 Rollup merge of #131890 - printfn:precise-capturing-docs, r=traviscross REVERT: 642ab07d02b Rollup merge of #127462 - Ayush1325:uefi-env, r=joboet REVERT: bac38912a1e Remove the Arc rt::init allocation for thread info REVERT: 85f6f48cb96 Auto merge of #131816 - Zalathar:profiler-feature, r=Kobzol REVERT: f843b262131 replace STATX_ALL with (STATX_BASIC_STATS | STATX_BTIME) as former is deprecated REVERT: aabdd7d597b zero-sized accesses are fine on null pointers REVERT: ff3f33f0147 Update `use` keyword docs to describe precise capturing REVERT: c949985e896 std: uefi: Use common function for UEFI shell REVERT: f973e62ee09 std: uefi: Add basic Env variables REVERT: 63a4a9bf56a Auto merge of #131895 - jieyouxu:rollup-jyt3pic, r=jieyouxu REVERT: 39ccfc9cfbb Rollup merge of #126207 - devnexen:stack_overflow_libc_upd, r=joboet REVERT: e08bce6edbf Auto merge of #131841 - paulmenage:futex-abstraction, r=joboet REVERT: 7f6af4dd882 Revert using `HEAP` static in Windows alloc REVERT: eba461cd50a Rollup merge of #131866 - jieyouxu:thread_local, r=jhpratt REVERT: 80bbaa966ed Rollup merge of #131858 - AnthonyMikh:AnthonyMikh/repeat_n-is-not-that-special-anymore, r=jhpratt REVERT: 5ec2cbcf4b0 Rollup merge of #131809 - collinoc:fix-retain-mut-docs, r=jhpratt REVERT: fe19eb64d14 Rollup merge of #131774 - thesummer:rtems-add-getentropy, r=joboet REVERT: fca737550f7 Rollup merge of #130136 - GKFX:stabilize-const-pin, r=dtolnay REVERT: 07aaa64759c Add entropy source for RTEMS REVERT: 1b957f4cc95 Rollup merge of #131850 - lexeyOK:master, r=compiler-errors REVERT: a6871b84557 Rollup merge of #131823 - thesummer:bump-libc-0.2.160, r=workingjubilee REVERT: 848aed94cd3 Rollup merge of #131654 - betrusted-io:xous-various-fixes, r=thomcc REVERT: a6e300e1fb6 Avoid shadowing user provided types or type aliases in `thread_local!` REVERT: a993e1de676 remove outdated documentation for `repeat_n` REVERT: 4d2c9694483 Auto merge of #131572 - cuviper:ub-index_range, r=thomcc REVERT: f905a0cd54e Bump libc to 0.2.161 REVERT: beee93f748d std::unix::stack_overflow::drop_handler addressing todo through libc update REVERT: c8f71dc9d2d Missing parenthesis REVERT: 01bce29cc5d Abstract the state type for futexes REVERT: 0ab703c6d44 Rollup merge of #131835 - ferrocene:amanjeev/add-missing-attribute-unwind, r=Noratrieb REVERT: bac74b68036 Rollup merge of #131833 - c-ryan747:patch-1, r=Noratrieb REVERT: 0d7c8897756 Auto merge of #130223 - LaihoE:faster_str_replace, r=thomcc REVERT: 34c8228660f Do not run test where it cannot run REVERT: d73f9242eab Add must_use to CommandExt::exec REVERT: aa027e9af5f Make `profiler_builtins` an optional dependency of sysroot, not std REVERT: 019ad0cab75 Remove TODO in proc_macro now `const_refs_to_static` is stable REVERT: 3b5d8a26f59 Fix predicate signatures in retain_mut docs REVERT: 6c85d31157b Auto merge of #131797 - matthiaskrgr:rollup-lzpze2k, r=matthiaskrgr REVERT: 3a5fdfc26a4 Partially stabilize const_pin REVERT: 7caa6d2fa3f Rollup merge of #131730 - zlfn:master, r=tgross35 REVERT: 1e13241be78 Auto merge of #131792 - matthiaskrgr:rollup-480nwg4, r=matthiaskrgr REVERT: 1581f568688 Rollup merge of #130822 - bjoernager:non-null-from-ref, r=dtolnay REVERT: f7b3231ad4c Auto merge of #131767 - cuviper:bump-stage0, r=Mark-Simulacrum REVERT: cdbd127ce77 Rollup merge of #131746 - slanterns:once_box_order, r=joboet REVERT: 6f3e65c5db7 Rollup merge of #131712 - tgross35:const-lazy_cell_into_inner, r=joboet REVERT: 151c0c71271 Auto merge of #131460 - jwong101:default-placement-new, r=ibraheemdev REVERT: 43f97fbcc51 update bootstrap configs REVERT: eae13d1eb36 replace placeholder version REVERT: e35d9fee2f0 relax a memory order in `once_box` REVERT: fbde7e89524 Rollup merge of #131521 - jdonszelmann:rc, r=joboet REVERT: 9d9ea42d6d4 Rollup merge of #130568 - eduardosm:const-float-methods, r=RalfJung,tgross35 REVERT: 435ce04088a Rollup merge of #129794 - Ayush1325:uefi-os-expand, r=joboet REVERT: bfd32fa365f Refactor `floating` macro and nofloat panic message REVERT: 7d1457e2a77 Auto merge of #131723 - matthiaskrgr:rollup-krcslig, r=matthiaskrgr REVERT: 148ed853756 Rename debug! macro to impl_Debug! REVERT: db2efb0ff0e Combine impl_int and impl_uint REVERT: 1897d05bfa1 Make some float methods unstable `const fn` REVERT: 76342d9978a Auto merge of #131724 - matthiaskrgr:rollup-ntgkkk8, r=matthiaskrgr REVERT: da7ca2278ec Rollup merge of #131706 - GKFX:fix-const-hacks, r=tgross35 REVERT: 54072ab6186 Rollup merge of #131496 - bjoernager:const-make-ascii, r=dtolnay REVERT: 1695b0a8e47 Rollup merge of #130608 - YohDeadfall:cstr-from-into-str, r=workingjubilee REVERT: f1ee2cd79c7 Rollup merge of #131339 - HeroicKatora:set_ptr_value-documentation, r=Mark-Simulacrum REVERT: ffc4a6cb394 Rollup merge of #122670 - beetrees:non-unicode-option-env-error, r=compiler-errors REVERT: cc7730e1264 Auto merge of #129458 - EnzymeAD:enzyme-frontend, r=jieyouxu REVERT: eeab9d49651 Stabilise 'const_make_ascii' REVERT: ec0b0dff72c Add a `const_sockaddr_setters` feature REVERT: e7884100078 Mark LazyCell::into_inner unstably const REVERT: acaf7e2e9ab Run most core::num tests in const context too REVERT: 63f38366fb6 Fix two const-hacks REVERT: 34d920c1aa6 `rt::Argument`: elide lifetimes REVERT: ecb3830a8b2 Rollup merge of #131384 - saethlin:precondition-tests, r=ibraheemdev REVERT: ea7a0c646f4 Rollup merge of #129424 - coolreader18:stabilize-pin_as_deref_mut, r=dtolnay REVERT: 843c9e98097 Auto merge of #131672 - matthiaskrgr:rollup-gyzysj4, r=matthiaskrgr REVERT: 3b92996e629 uefi: Implement getcwd and chdir REVERT: 8d35aa977cc Rollup merge of #131616 - RalfJung:const_ip, r=tgross35 REVERT: b6cfaeb1239 Rollup merge of #131274 - workingjubilee:stabilize-the-one-that-got-away, r=scottmcm REVERT: 6d8235e8adb Rollup merge of #130629 - Dirbaio:net-from-octets, r=tgross35 REVERT: 88634c8310a Rollup merge of #128967 - devnexen:get_path_fbsd_upd, r=joboet REVERT: d6318f3817a Auto merge of #126557 - GrigorenkoPV:vec_track_caller, r=joboet REVERT: 541bda102a0 Implement file_lock feature REVERT: d11e388017f Auto merge of #131662 - matthiaskrgr:rollup-r1wkfxw, r=matthiaskrgr REVERT: 089c495282b rename rcbox in other places as per review comments REVERT: 2cfa6d06db7 core/net: use hex for ipv6 doctests for consistency. REVERT: 9ae0e8bcfaf core/net: add Ipv[46]Addr::from_octets, Ipv6Addr::from_segments REVERT: da6c63c5a39 Rollup merge of #131646 - RalfJung:unix-miri-fallbacks, r=joboet REVERT: 87ea4bb9c12 Rollup merge of #131644 - RalfJung:win-miri, r=joboet REVERT: 928b99c635c library: xous: mark alloc as `FIXME(static_mut_refs)` REVERT: dde2ff0ebe8 xous: ffi: correct syscall number for adjust_process REVERT: c3955e47308 net: fix dead code warning REVERT: 3919c4f32a0 std: xous: add support for args and env REVERT: 9c1e16259db Auto merge of #125679 - clarfonthey:escape_ascii, r=joboet REVERT: 262c3fb4d69 unwind: update unwinding dependency to 0.2.3 REVERT: 4c6374963e6 sys/unix: add comments for some Miri fallbacks REVERT: e3f701c4b40 remove outdated comment now that Miri is on CI REVERT: e2c210e67f8 sys/windows: remove miri hack that is only needed for win7 REVERT: 1799481f55c switch unicode-data back to 'static' REVERT: ddfd2ea502a merge const_ipv4 / const_ipv6 feature gate into 'ip' feature gate REVERT: b6c03764111 Rollup merge of #131418 - coolreader18:wasm-exc-use-stdarch, r=bjorn3 REVERT: 1ee9b69f828 Rollup merge of #131120 - tgross35:stabilize-const_option, r=RalfJung REVERT: 6fc4b1a9f8b Fix bug where `option_env!` would return `None` when env var is present but not valid Unicode REVERT: d72915fce78 Fix typo thing->thin referring to pointer REVERT: a2d85a1f8b8 Stabilize `const_option` REVERT: 4a9ad4ac8cc Rollup merge of #131617 - RalfJung:const_cow_is_borrowed, r=tgross35 REVERT: 113c6c093fa Rollup merge of #131503 - theemathas:stdin_read_line_docs, r=Mark-Simulacrum REVERT: 7a515952c92 remove const_cow_is_borrowed feature gate REVERT: 7420c36fae4 Rollup merge of #131233 - joboet:stdout-before-main, r=tgross35 REVERT: 08e7188f626 Rollup merge of #130954 - workingjubilee:stabilize-const-mut-fn, r=RalfJung REVERT: 3febfb34f55 std: fix stdout-before-main REVERT: 3b820ee5e01 library: Stabilize `const_replace` REVERT: ee21064fde0 library: Stabilize `const_ptr_write` REVERT: 36ff2c84d56 library: Stabilize `const_intrinsic_forget` REVERT: 4f124de46bd Rollup merge of #131289 - RalfJung:duration_consts_float, r=tgross35 REVERT: de76914d8c6 Rollup merge of #130962 - nyurik:opts-libs, r=cuviper REVERT: 76ce3a99e3a Rollup merge of #124874 - jedbrown:float-mul-add-fast, r=saethlin REVERT: de18ce14fb9 Avoid superfluous UB checks in `IndexRange` REVERT: eb8ff202d9e Rollup merge of #131463 - bjoernager:const-char-encode-utf8, r=RalfJung REVERT: 964c91b858a Rollup merge of #131287 - RalfJung:const_result, r=tgross35 REVERT: a8b0950a043 Rollup merge of #131109 - tgross35:stabilize-debug_more_non_exhaustive, r=joboet REVERT: 637b5152fc6 Rollup merge of #131065 - Voultapher:port-sort-test-suite, r=thomcc REVERT: eeb881dee88 intrinsics.fmuladdf{16,32,64,128}: expose llvm.fmuladd.* semantics REVERT: 2b6b22cebab Single commit implementing the enzyme/autodiff frontend REVERT: 00785c0149e stabilize const_result REVERT: 12b80281dcd stabilize duration_consts_float REVERT: c8d357c99d6 Rollup merge of #131512 - j7nw4r:master, r=jhpratt REVERT: 34f7831c7de rename RcBox in other places too REVERT: cd0a8f50855 rename RcBox to RcInner for consistency REVERT: dd6dd70c0fd Fixing rustDoc for LayoutError. REVERT: 7fdd5455da9 Rollup merge of #130741 - mrkajetanp:detect-b16b16, r=Amanieu REVERT: 77f7b2fe97e Rollup merge of #130538 - ultrabear:ultrabear_const_from_ref, r=workingjubilee REVERT: d7a7b0a361b uefi: process: Add args support REVERT: 14aef3d76cf Use with_capacity(0) because we're reading the capacity later on REVERT: 5b16abea8d5 Prefer `target_vendor = "apple"` on confstr REVERT: bc6398107f8 use `confstr(_CS_DARWIN_USER_TEMP_DIR, ...)` as a `TMPDIR` fallback on darwin REVERT: fca091985c1 More clearly document Stdin::read_line REVERT: e4a9064e4d6 Stabilise 'const_char_encode_utf8'; REVERT: 8547f513811 allocate before calling T::default in >::default() REVERT: 669e25597c8 allocate before calling T::default in >::default() REVERT: 5ef6f834a52 rustc_target: Add sme-b16b16 as an explicit aarch64 target feature REVERT: 74264e37655 stdarch: Bump stdarch submodule REVERT: a5529ee2982 Clean up is_aligned_and_not_null REVERT: db5a9a7f814 Add more precondition check tests REVERT: 528dda2686f Allow zero-size reads/writes on null pointers REVERT: 86c75265bd5 Optimize escape_ascii REVERT: 36a90d74101 Rollup merge of #131462 - cuviper:open_buffered-error, r=RalfJung REVERT: 49220cd15f1 Rollup merge of #131449 - nickrum:wasip2-net-decouple-fd, r=alexcrichton REVERT: ff37c087e49 Rollup merge of #131383 - AngelicosPhosphoros:better_doc_for_slice_slicing_at_ends, r=cuviper REVERT: 136ec3ace84 Rollup merge of #130827 - fmease:library-mv-obj-save-dyn-compat, r=ibraheemdev REVERT: 8cdea8c34b0 Add "not guaranteed to be equal" REVERT: db9377d33aa Mention allocation errors for `open_buffered` REVERT: 7e225fa8a49 Apply suggestions from code review REVERT: 0ce4f76a7d5 Expand `ptr::fn_addr_eq()` documentation. REVERT: 885e3d14d82 Library: Rename "object safe" to "dyn compatible" REVERT: 5f495eef33c Decouple WASIp2 sockets from WasiFd REVERT: 78670fb644f stabilize `{slice,array}::from_mut` REVERT: 7153288b527 Update library/std/src/sys/pal/unix/process/process_vxworks.rs REVERT: cd0d5be2726 fix ref in process_vxworks.rs REVERT: 01e7f5f97b1 Update library/std/src/sys/pal/unix/process/process_unix.rs REVERT: fbb514cbba3 Change a few `&Option` into `Option<&T>` REVERT: cc1e8b56f8f Use throw intrinsic from stdarch in wasm libunwind REVERT: bc755bb5124 Stabilize Pin::as_deref_mut REVERT: fcc990d33eb Stabilize `isqrt` feature REVERT: f8dc879fa96 Add LowerExp and UpperExp implementations REVERT: b946b83a26a Add docs about slicing slices at the ends REVERT: 9ca739e65a6 cfg out checks in add and sub but not offset REVERT: 8293e745abb Add precondition checks to ptr::offset, ptr::add, ptr::sub REVERT: c65244c638a Rollup merge of #131308 - mati865:gnullvm-f16-f128, r=tgross35 REVERT: 6a809c73fad Rollup merge of #128399 - mammothbane:master, r=Amanieu,tgross35 REVERT: 723693ef035 liballoc: introduce String, Vec const-slicing REVERT: fee7e5e4dbb Auto merge of #128651 - folkertdev:naked-asm-macro-v2, r=Amanieu REVERT: 61eff8fd543 Expand set_ptr_value / with_metadata_of docs REVERT: 7c3b7e72f68 Rollup merge of #131335 - dacianpascu06:fix-typo, r=joboet REVERT: 8e3076e7875 Rollup merge of #131307 - YohDeadfall:prctl-set-name-dbg-assert, r=workingjubilee REVERT: b8c51a660a1 grammar fix REVERT: 4ca50c3c94a disallow `asm!` in `#[naked]` functions REVERT: cc09cb0dfa4 implement `naked_asm` macro REVERT: dbb22815a85 Rollup merge of #131316 - programmerjake:patch-4, r=Noratrieb REVERT: 4b276e63ed9 Auto merge of #131314 - tgross35:update-builtins, r=tgross35 REVERT: 5dc3e7cf205 Fix typo in primitive_docs.rs REVERT: 686d25dc005 Auto merge of #130540 - veera-sivarajan:fix-87525, r=estebank REVERT: 9555c10cffb Update `compiler-builtins` to 0.1.133 REVERT: 0f71b38a203 enable f16 and f128 on windows-gnullvm targets REVERT: d14d771cf46 Auto merge of #131302 - matthiaskrgr:rollup-56kbpzx, r=matthiaskrgr REVERT: b8dd44198e9 Android: Debug assertion after setting thread name REVERT: fcd199dec5f Rollup merge of #131281 - RalfJung:const-cell, r=Amanieu REVERT: 71aa514ef59 Auto merge of #131221 - XrXr:bump-compiler-builtins, r=tgross35 REVERT: b7c90c62514 library: Stabilize const `MaybeUninit::assume_init_mut` REVERT: 0418d546ad5 Add a Lint for Pointer to Integer Transmutes in Consts REVERT: 460459d3c24 Rollup merge of #131256 - RalfJung:f16-f128-const, r=ibraheemdev REVERT: a818a4dfa97 Rollup merge of #131094 - joboet:lazy_once_box, r=ibraheemdev REVERT: 2ed62821f6a make Cell unstably const REVERT: 575391b7daf move f16/f128 const fn under f16/f128 feature gate REVERT: b3da4ed72f7 Stabilize `const_slice_split_at_mut` and `const_slice_first_last_chunk` REVERT: bbe8bf7f827 Rollup merge of #131267 - okaneco:bufread_skip_until, r=tgross35 REVERT: 65049d1b3a2 Rollup merge of #131105 - slanterns:literal_c_str, r=petrochenkov REVERT: 7001dd5a296 Rollup merge of #130403 - eduardosm:stabilize-const_slice_from_raw_parts_mut, r=workingjubilee REVERT: 0f43ffb1b78 Update compiler-builtins to 0.1.132 REVERT: 7d4319e623c Rollup merge of #131177 - workingjubilee:stabilize-const-mut-referees, r=tgross35 REVERT: 67093076d45 Rollup merge of #130518 - scottmcm:stabilize-controlflow-extra, r=dtolnay REVERT: b732d237348 Stabilize `BufRead::skip_until` REVERT: eb2806b2450 Auto merge of #130157 - eduardosm:stabilize-const_float_classify, r=RalfJung REVERT: 50afc521a17 Stabilize UnsafeCell::from_mut REVERT: c822d330b90 update libc version REVERT: 26b231be7ab std::fs::get_path freebsd update. REVERT: 1bd16cdc12d Rollup merge of #131197 - EFanZh:avoid-emptyness-check-in-peekmut-pop, r=Amanieu REVERT: 8cfa0cad753 Avoid emptiness check in `PeekMut::pop` REVERT: 86fa4749d71 Rollup merge of #131163 - JakenHerman:master, r=Nadrieril REVERT: 6b57e57feb7 Auto merge of #128711 - clarfonthey:default-iters-hash, r=dtolnay REVERT: 254af0b5676 Add `get_line` confusable to `Stdin::read_line()` REVERT: f89b8dc4085 impl Default for Hash{Map,Set} iterators that don't already have it REVERT: 0c22ea874b0 Auto merge of #127912 - joboet:tls_dtor_thread_current, r=cuviper REVERT: 2b4f6ec1c62 Auto merge of #131148 - Urgau:hashbrown-0.15, r=Amanieu REVERT: 26013cd95f9 library: Stabilize `const_slice_first_last` REVERT: 51ed903979b library: Stabilize `const_unsafecell_get_mut` REVERT: cd6c1cc10b9 library: Stabilize `const_ptr_as_ref` REVERT: ecb0f03e4e2 library: Stabilize `const_str_as_mut` REVERT: 78ad293f3b4 library: Stabilize `const_str_from_utf8_unchecked_mut` REVERT: db56087d227 std: make `thread::current` available in all `thread_local!` destructors REVERT: d5599a7e273 Rollup merge of #131141 - RalfJung:mpmc-test, r=Amanieu REVERT: 487946f8cef Update hashbrown to 0.15 and adjust some methods REVERT: 0d191198a22 mpmc doctest: make sure main thread waits for child threads REVERT: a7d53dad608 Auto merge of #130829 - Urgau:option_array_transpose, r=ibraheemdev REVERT: 7c896fc637d Auto merge of #128204 - GuillaumeGomez:integers-opti, r=workingjubilee REVERT: f19cac15d11 std: replace `LazyBox` with `OnceBox` REVERT: e2ebf0447a4 Stabilize `const_slice_from_raw_parts_mut` REVERT: a575a8b0d73 Auto merge of #131111 - matthiaskrgr:rollup-n6do187, r=matthiaskrgr REVERT: 82e1372c75b Rollup merge of #130773 - bjoernager:master, r=thomcc REVERT: b33d815cbba Rollup merge of #130229 - RalfJung:ptr-offset-unsigned, r=scottmcm REVERT: bf40ab27b3b Implemented FromStr for CString and TryFrom for String REVERT: ea51d16d7c0 Stabilize `debug_more_non_exhaustive` REVERT: f8db8779429 update `Literal`'s intro REVERT: bcfd953c29e Auto merge of #131098 - GuillaumeGomez:rollup-kk74was, r=GuillaumeGomez REVERT: 3a8939e2d3c Rollup merge of #131085 - RalfJung:miri-slow-test, r=tgross35 REVERT: 90d63b16b5c Auto merge of #126839 - obeis:mpmc, r=Amanieu REVERT: 4451aeededb Remove the need to provide the maximum number of digits to `impl_Display` macro REVERT: 85c1cec695e Simplify `impl_Display` macro REVERT: c4be3da8440 Small optimization for integers Display implementation REVERT: 82014ee9988 make test_lots_of_insertions test take less long in Miri REVERT: f688d7d81d0 Enable `f16` tests on non-GNU Windows REVERT: e97c379df19 Rollup merge of #130966 - RalfJung:ptr-metadata-const-stable, r=scottmcm REVERT: e4d621e29b6 Rollup merge of #130961 - tgross35:f16-x86-apple, r=thomcc REVERT: 3c9808bdfcf Rollup merge of #130914 - compiler-errors:insignificant-dtor, r=Amanieu REVERT: 99e98538bb5 Rollup merge of #129638 - nickrum:wasip2-net, r=alexcrichton REVERT: e2a020e6863 Add multi-producer, multi-consumer channel (mpmc) REVERT: cbc9e287756 Port sort-research-rs test suite Rust stdlib tests REVERT: b36201981bc Rollup merge of #130972 - RalfJung:const_cell_into_inner, r=dtolnay REVERT: 109f2701e8b Rollup merge of #129003 - Voultapher:improve-ord-docs, r=workingjubilee REVERT: 07542a5c170 Rollup merge of #123932 - adamse:global-alloc-safety-preconds-positive, r=tgross35 REVERT: 2332c3d1a72 Rollup merge of #130931 - GuillaumeGomez:standalone-crate, r=notriddle REVERT: faa018ecfa8 Rename doctest attribute `standalone-crate` into `standalone_crate` for coherency REVERT: e36be64bdf1 Rollup merge of #130743 - YohDeadfall:net-nonblocking-doc, r=Mark-Simulacrum REVERT: a31f8828ccc Rollup merge of #130416 - BatmanAoD:130122-sort-by-docs, r=Mark-Simulacrum REVERT: 08ac3a03cfd Remove duplicate section REVERT: b4307a53105 Auto merge of #128321 - BatmanAoD:catch-unwind-doc-update, r=Mark-Simulacrum REVERT: 9ae087ce909 Fix std tests for wasm32-wasip2 target REVERT: b0cc90202cd Hook up std::net to wasi-libc on wasm32-wasip2 target REVERT: 7311aa8d2c7 Auto merge of #123778 - jhorstmann:optimize-upper-lower-auto-vectorization, r=the8472 REVERT: c3d3d1a1216 Enable `f16` tests on x86 Apple platforms REVERT: 3aae77071a0 Auto merge of #129385 - tgross35:more-platforms-enable-f16, r=Mark-Simulacrum REVERT: 26407360225 Auto merge of #130792 - tgross35:update-builtins, r=Amanieu REVERT: 383f0def784 Rename `standalone` doctest attribute into `standalone-crate` REVERT: 1f8a7736596 Update compiler_builtins to 0.1.130 REVERT: 7a5052a8ef7 Rollup merge of #128778 - RalfJung:atomic-read-read-races, r=Mark-Simulacrum REVERT: 098ada160f7 Auto merge of #130964 - matthiaskrgr:rollup-suriuub, r=matthiaskrgr REVERT: 81fcbcd76e6 Further clarificarion for atomic and UnsafeCell docs: REVERT: e7c99a7ec72 allow mixed-size atomic reads REVERT: addd05ec29a atomics: allow atomic and non-atomic reads to race REVERT: b8c2a2a31e9 stabilize const_cell_into_inner REVERT: 7946445e4ab make ptr metadata functions callable from stable const fn REVERT: 9f50f5ab7e1 Auto merge of #130897 - workingjubilee:dump-hexes-with-class, r=thomcc REVERT: e66058d77a1 Rollup merge of #130922 - tyilo:udp-unspecified, r=ibraheemdev REVERT: 1bd2532dc81 Rollup merge of #125404 - a1phyr:fix-read_buf-uses, r=workingjubilee REVERT: 288b9ca02b0 Update Unicode escapes; REVERT: 05590f7156d Enable `f16` on platforms that were missing conversion symbols REVERT: 3a00bff8352 Auto merge of #130946 - matthiaskrgr:rollup-ia4mf0y, r=matthiaskrgr REVERT: c2bd1e39c40 Rollup merge of #130926 - ChrisDenton:cc-1-1-22, r=tgross35 REVERT: 7ddd56672f4 Rollup merge of #129087 - slanterns:option_get_or_insert_default, r=dtolnay REVERT: 93916ed57b0 Mark some more smart pointers as insignificant REVERT: 118d2e4c7dc Mark some more types as having insignificant dtor REVERT: 9b4776b272b Add 'from_ref' and 'from_mut' constructors to 'core::ptr::NonNull'; REVERT: 56523a9df37 Update Cargo.lock REVERT: aabd713b24b Apply review feedback REVERT: df28bde6c18 Apply round 1 of review comments REVERT: cb0529a1e28 Fix mistake in example REVERT: a9eb97b8682 Improve Ord docs REVERT: 04d91457f81 Reference UNSPECIFIED instead of INADDR_ANY in join_multicast_v4 REVERT: edc72ca4a4b Rollup merge of #130892 - tgross35:library-cargo-update, r=Noratrieb REVERT: fdf84bfd56d Rollup merge of #130875 - folkertdev:naked-asm-bootstrap, r=tgross35 REVERT: 1b3f488a588 Rollup merge of #130846 - ChrisDenton:revert-break, r=Noratrieb REVERT: 89c9ef65418 Rollup merge of #130313 - c410-f3r:unlock-rfc-2011, r=thomcc REVERT: ea82a9668f4 Rollup merge of #130880 - RalfJung:const-hack, r=scottmcm REVERT: be1d9d67900 Rollup merge of #130861 - cuviper:sun-path-offset, r=ibraheemdev REVERT: c1c0a1b5a4d Rollup merge of #130845 - RalfJung:utf8chunk, r=tgross35 REVERT: 805d196d6a7 Rollup merge of #130279 - theemathas:manually-drop-docs, r=thomcc,traviscross REVERT: f40ec5aecf4 library: Compute `RUST_EXCEPTION_CLASS` from native-endian bytes REVERT: eae051bb5e2 Partially update `library/Cargo.lock` REVERT: 532cd8551de Add `sun_path` to the fake doc `sockaddr_un` REVERT: f0660deaec1 add missing FIXME(const-hack) REVERT: 0580e66c287 Add `[Option; N]::transpose` REVERT: 13417248b26 update `compiler_builtins` to `0.1.126` REVERT: cd704d4c632 add a bootstrap variant of `naked_asm` REVERT: a781a4a638a Stabilize the `map`/`value` methods on `ControlFlow` REVERT: ff453134135 Use `&raw` in the standard library REVERT: 3d036345362 Use `mem::offset_of!` for `sockaddr_un.sun_path` REVERT: f50b2ba584d Rollup merge of #130842 - Noratrieb:tracking-issue-inprogress, r=jieyouxu REVERT: c50befe9ea0 Rollup merge of #130832 - RalfJung:sort-cfg-mess, r=workingjubilee REVERT: d50c54a1171 Rollup merge of #130819 - bjoernager:char-must-use-len-utf, r=Noratrieb REVERT: 811ce7762b6 Rollup merge of #130811 - RalfJung:random, r=joboet REVERT: 275fb0eb691 Revert Break into the debugger on panic (129019) REVERT: f560508bef1 Utf8Chunks: add link to Utf8Chunk REVERT: 88474293f4b Add tracking issue for io_error_inprogress REVERT: fa38b29687b fix some cfg logic around optimize_for_size and 16-bit targets REVERT: b9ef35a8f73 Auto merge of #130816 - matthiaskrgr:rollup-jy25phv, r=matthiaskrgr REVERT: e4f89ece58f Add 'must_use' attribute to 'char::len_utf8' and 'char::len_utf16'; REVERT: bcb9d2385d9 Rollup merge of #130810 - kromych:master, r=workingjubilee REVERT: a5a32e2c8f0 Rollup merge of #130595 - no1wudi:master, r=ibraheemdev REVERT: 6a06555427f Rollup merge of #130549 - biabbas:riscv32_wrs_vxworks, r=nnethercote REVERT: f67efdd34d8 add link from random() helper fn to extensive DefaultRandomSource docs REVERT: 4a7aeff64ec Auto merge of #130803 - cuviper:file-buffered, r=joshtriplett REVERT: 54834b6bae3 Don't trap into the debugger on panics under Linux REVERT: 2c408b10a25 Rollup merge of #130789 - aviramha:add_inprogress, r=Noratrieb REVERT: 8849d13a2f0 Rollup merge of #130788 - tgross35:memchr-pinning, r=Noratrieb,Mark-Simulacrum REVERT: 2ab86f01c97 Add a tracking issue for `file_buffered` REVERT: 963cefb2cd1 Dogfood `feature(file_buffered)` REVERT: aa74e934264 Mark 'get_mut' and 'set_position' in 'std::io::Cursor' as const; REVERT: 15d69c9edf4 Pre-allocate buffers in `File::open_buffered` and `create_buffered` REVERT: eb07a61acf1 Add `File::open_buffered` and `create_buffered` REVERT: 92d5cef2a6a Auto merge of #129587 - Voultapher:opt-for-size-variants-of-sort-impls, r=cuviper REVERT: c86f1ce711b add InProgress ErrorKind gated behind io_error_inprogress feature REVERT: 6d8f5d81b18 Pin memchr to 2.5.0 in the library rather than rustc_ast REVERT: 194bbc77c56 Auto merge of #130738 - bjoernager:const-make-ascii, r=jhpratt REVERT: c47920fa3a5 Initial std library support for NuttX REVERT: 622d08c26df Mark and implement 'make_ascii_uppercase' and 'make_ascii_lowercase' in '[u8]' and 'str' as const; REVERT: 668b21ae951 Rollup merge of #130762 - RalfJung:const_intrinsic_copy, r=dtolnay REVERT: 43a4d34efd2 Rollup merge of #129545 - notriddle:notriddle/toolbar-v2, r=GuillaumeGomez REVERT: 57557c9629f Add a comment to `Read::read_buf` REVERT: 4a11249c0f7 Add tests REVERT: f34267540ce Fix `io::default_read_to_end` uses of `read_buf` REVERT: 57f279d91b7 Fix `io::BufReader` uses of `read_buf` REVERT: 8472204d13e Fix `io::Take::read_buf` REVERT: db0f33788d6 stabilize const_intrinsic_copy REVERT: 27136c4a376 Add fast path for ascii to ascii in str::replace REVERT: fc983bafafc Fix up standard library intro REVERT: 6d41b99edf7 Clarifications for set_nonblocking methods REVERT: f5406a512b8 Improve autovectorization of to_lowercase / to_uppercase functions REVERT: bab810c740a random: add tracking issue, address other comments REVERT: 849258c77c2 std: switch to faster random sources on macOS and most BSDs REVERT: a095a76d3a7 std: implement the `random` feature REVERT: ba6158c689b Rollup merge of #130723 - D0liphin:master, r=workingjubilee REVERT: 776d9eff4dc Rollup merge of #130713 - bjoernager:const-char-make-ascii, r=Noratrieb REVERT: 337c634511c Rollup merge of #130659 - bjoernager:const-char-encode-utf16, r=dtolnay REVERT: 8ffc1707657 Rollup merge of #129550 - kornelski:boxasstr, r=joshtriplett,dtolnay REVERT: a28cdffc73b Reformat using the new identifier sorting from rustfmt REVERT: 07a62f42f5d reword edge-conditions documentation on all slice 'sort' functions; resolves #130122 REVERT: 9bcb2d9551e Add test for `available_parallelism()` REVERT: 474b9af1e61 Mark 'make_ascii_uppercase' and 'make_ascii_lowercase' in 'u8' as const; Rename 'const_char_make_ascii' feature gate to 'const_make_ascii'; REVERT: b3d4fde409e Rollup merge of #130692 - RalfJung:result-flatten, r=Noratrieb REVERT: 55becb00610 Rollup merge of #130670 - the8472:read-to-end-heuristics, r=ChrisDenton REVERT: 202df818d33 Rollup merge of #130658 - EqualMa:patch-1, r=scottmcm REVERT: 9c26e05665e Auto merge of #130697 - bjoernager:const-char-make-ascii, r=dtolnay REVERT: 36b115fba8d Mark 'make_ascii_uppercase' and 'make_ascii_lowercase' in 'char' as const; REVERT: 98aba66e96e make unstable Result::flatten a const fn REVERT: d0989933442 Rollup merge of #130653 - RalfJung:result-abi-compat, r=traviscross REVERT: 2953dee0e23 Rollup merge of #130408 - okaneco:into_lossy_refactor, r=Noratrieb REVERT: 94105e87d4f wait for two short reads before uncapping the max read size REVERT: dea467af191 Mark and implement 'char::encode_utf16' as const; Rewrite 'encode_utf16_raw'; REVERT: 49128a49622 Fix docs of compare_bytes REVERT: db6427b456d ABI compatibility: mention Result guarantee REVERT: 1632f8f88e8 Reword ManuallyDrop+Box interaction REVERT: 4969ea81953 Rollup merge of #129718 - lolbinarycat:remove_dir-docs, r=Noratrieb REVERT: c11b3aa4a78 Avoid re-validating UTF-8 in `FromUtf8Error::into_utf8_lossy` REVERT: 93f5e21e0f0 Auto merge of #130631 - GuillaumeGomez:rollup-jpgy1iv, r=GuillaumeGomez REVERT: a7aac1ef4d2 Remove double spaces REVERT: 74935ec3185 Rollup merge of #130624 - theemathas:vec_as_non_null, r=Noratrieb REVERT: 2c9a4e3f2b2 Rollup merge of #130611 - bjoernager:const-char-encode-utf8, r=dtolnay REVERT: 25ab8efde9f Rollup merge of #130526 - eholk:pin-reborrow, r=compiler-errors REVERT: 97c4937a933 Rollup merge of #128209 - beetrees:no-macos-10.10, r=jieyouxu REVERT: 3e5c662a8b4 Auto merge of #124895 - obeis:static-mut-hidden-ref, r=compiler-errors REVERT: 31d575bd5a0 Add `Vec::as_non_null` REVERT: 54e23b5d765 Address diagnostics regression for 'const_char_encode_utf8'; REVERT: 557a0b8ac2e Allow unused unsafe for vxworks in alligned_malloc to resolve build errors REVERT: 7ae682789c0 [Clippy] Remove final std paths for diagnostic item REVERT: 7b1c5e87b84 Allow shortening reborrows REVERT: 86240c7ca53 Add `#[track_caller]` to allocating methods of `Vec` & `VecDeque` REVERT: 33945576c22 Rollup merge of #130554 - ShE3py:unsupported-exitcode, r=Noratrieb REVERT: 17b0e39d3a9 Rollup merge of #130553 - GnomedDev:remove-clippy-paths, r=compiler-errors REVERT: 64a59842bb1 Rollup merge of #128001 - Krappa322:master, r=scottmcm REVERT: 81c4805e8ad Add str.as_str() for easy dereferencing of Box REVERT: 4ea6b8269c5 `pal::unsupported::process::ExitCode`: use an `u8` instead of a `bool` REVERT: cb771b22bc6 [Clippy] Swap `open_options` to use diagnostic items instead of paths REVERT: 04bd505e545 [Clippy] Swap `iter_over_hash_type` to use diagnostic items instead of paths REVERT: 8147cf45a26 [Clippy] Swap `non_octal_unix_permissions` to use diagnostic item instead of path REVERT: 1b0be2aa317 [Clippy] Swap `unnecessary_owned_empty_strings` to use diagnostic item instead of path REVERT: 9edfe1dc97f [Clippy] Swap `manual_strip` to use diagnostic items instead of paths REVERT: 995238ce3f5 [Clippy] Swap `unnecessary_to_owned` to use diagnostic item instead of path REVERT: c1a4a69d65a [Clippy] Swap `instant_subtraction` to use diagnostic item instead of path REVERT: beaebb53af0 [Clippy] Swap `waker_clone_wake` to use diagnostic item instead of path REVERT: 925c1c4ffc8 [Clippy] Swap `filter_map_bool_then` to use diagnostic item instead of path REVERT: 7bc30a7e0d1 [Clippy] Swap `manual_while_let_some` to use diagnostic items instead of paths REVERT: 08b676d07d8 [Clippy] Swap `repeat_vec_with_capacity` to use diagnostic item instead of path REVERT: b95bef03da4 [Clippy] Swap `VecArgs::hir` to use diagnostic items instead of paths REVERT: 6906fa9d9f5 [Clippy] Swap `single_char_add_str`/`format_push_string` to use diagnostic items instead of paths REVERT: b2dc66e63fe [Clippy] Swap `manual_main_separator_str` to use diagnostic item instead of path REVERT: a61b7b74edc [Clippy] Swap `redundant_clone` to use diagnostic items instead of paths REVERT: 3310a0ba289 [Clippy] Swap `float_equality_without_abs` to use diagnostic items instead of paths REVERT: 6ef72c4aead [Clippy] Swap `option_as_ref_deref` to use diagnostic items instead of paths REVERT: b8c0c3b59d6 [Clippy] Swap `lines_filter_map_ok` to use a diagnostic item instead of path REVERT: 116e527af29 [Clippy] Swap `map_entry` to use diagnostic items instead of paths REVERT: 03ff0df4056 Auto merge of #130547 - workingjubilee:rollup-tw30khz, r=workingjubilee REVERT: 6210ecb4fdb Auto merge of #130511 - bjoernager:const-char-encode-utf8, r=dtolnay REVERT: ccb31b838d9 run `x.py fmt` REVERT: 9510c7695c8 remove feature attributes as const_maybe_uninit_as_mut_ptr is stabilized REVERT: c12546bbad7 stabilize `const_maybe_uninit_as_mut_ptr` REVERT: e94c0809293 Mark and implement 'char::encode_utf8' as const. REVERT: 150994417ab Rollup merge of #130522 - GnomedDev:clippy-manual-retain-paths, r=compiler-errors REVERT: 8a9576c7fe5 Rollup merge of #130513 - shekhirin:fs-write-doc-comment, r=cuviper REVERT: d53d48a35c6 Rollup merge of #130487 - cuviper:min-llvm-18, r=nikic REVERT: f63c0c181dc Rollup merge of #130476 - workingjubilee:more-lazy-methods-take-2, r=Amanieu REVERT: 09e36adc31d Rollup merge of #129934 - ChrisDenton:remove-dir-all3, r=Amanieu REVERT: 5480d57c571 Rollup merge of #97524 - ibraheemdev:thread-raw, r=ibraheemdev REVERT: 886fc13b4a6 Revert "Add a hack to prevent proc_macro misopt in CI" REVERT: 56704d424c8 Begin experimental support for pin reborrowing REVERT: 262a08b3220 library: Call it really_init_mut to avoid name collisions REVERT: 51023b58e9b library: Destabilize Lazy{Cell,Lock}::{force,deref}_mut REVERT: ff51d9fe674 [Clippy] Swap `manual_retain` to use diagnostic items instead of paths REVERT: 28695bfc395 Auto merge of #130497 - saethlin:alloc-zeroed-is-unstable, r=bjorn3 REVERT: 8f6ca5b3867 Clarify docs for std::fs::File::write REVERT: b19bf06090d Auto merge of #129491 - StackOverflowExcept1on:master, r=m-ou-se REVERT: 37eb770d8c1 Auto merge of #129845 - scottmcm:redo-layout, r=Noratrieb REVERT: cc10a764910 Take more advantage of the `isize::MAX` limit in `Layout` REVERT: d740b8d22b1 read_volatile __rust_no_alloc_shim_is_unstable in alloc_zeroed REVERT: e65d8e8dfef Rollup merge of #130481 - krtab:clamp_partial_ord, r=cuviper REVERT: f3a53b7c4de Auto merge of #130483 - matthiaskrgr:rollup-q1r0g0y, r=matthiaskrgr REVERT: 46a0aa844f2 Remove uneeded PartialOrd bound in cmp::Ord::clamp REVERT: c83fbfd2017 Rollup merge of #130467 - RalfJung:miri-sync, r=RalfJung REVERT: 6893990b5ba Rollup merge of #129674 - matthewpipie:rc-arc-new-cyclic-in, r=dtolnay REVERT: a0f4a4b3281 Implement ACP 429: add `Lazy{Cell,Lock}::get[_mut]` and `force_mut` REVERT: 7505e2956ba Rollup merge of #128535 - mmvanheusden:master, r=workingjubilee REVERT: 8a5922fb084 Auto merge of #130145 - fee1-dead-contrib:repeatn, r=lcnr,workingjubilee REVERT: c15d489d04d Merge from rustc REVERT: e80d16cdf1e Rollup merge of #130448 - alilleybrinker:master, r=workingjubilee REVERT: cd8a7af7d0e Update library/alloc/src/sync.rs REVERT: 2819604711d Auto merge of #127633 - SamuelMarks:eq-exit-code, r=dtolnay REVERT: 49a855dba5e fix: Remove duplicate `LazyLock` example. REVERT: 9af97fc0a10 Rollup merge of #127879 - kornelski:bad-pointer-printf, r=workingjubilee REVERT: 2c1bd02a09a Merge from rustc REVERT: fc9c9009d26 Auto merge of #130220 - RalfJung:float-classify, r=workingjubilee REVERT: 35edcb6461b update docs for `catch_unwind` & related funcs REVERT: ee67105e0ae Rollup merge of #130339 - CAD97:unwind-choice, r=dtolnay REVERT: f3968493684 simplify abort_unwind REVERT: b66efddccf2 Rollup merge of #129439 - okaneco:vec_string_lossy, r=Noratrieb REVERT: af73374905e Rollup merge of #130381 - workingjubilee:sometimes-code-really-is-self-descriptive, r=Noratrieb REVERT: 524402a0fd4 Rollup merge of #130118 - RalfJung:unwrap_unchecked, r=Noratrieb REVERT: 3dccb864068 Rollup merge of #129195 - RalfJung:const-mut-refs, r=fee1-dead REVERT: 524a5e14330 also stabilize const_refs_to_cell REVERT: 29c8eef74ff const_refs_to_cell: dont let mutable references sneak past the interior mutability check REVERT: 5671193598c stabilize const_mut_refs REVERT: 085baa2b96e library: Compute Rust exception class from its string repr REVERT: fc53427da98 Rollup merge of #130214 - RalfJung:zeroed, r=Mark-Simulacrum REVERT: 0e7d343962e Rollup merge of #130061 - theemathas:box_vec_non_null, r=MarkSimulacrum,workingjubilee REVERT: 09f1d40a239 Rollup merge of #130042 - lolbinarycat:bufreaker_peek_eof, r=Amanieu REVERT: 0fd6e237ada Add tracking issue number for `box_vec_non_null` REVERT: d38c59a2454 Rollup merge of #130290 - passcod:stabilise-entry-insert, r=ChrisDenton REVERT: 96b5b7cd3e6 Rollup merge of #130268 - RalfJung:simd-shuffle-idx-vector, r=compiler-errors REVERT: 79d937d0854 simd_shuffle: require index argument to be a vector REVERT: 857ad2299b8 Rollup merge of #130053 - glowcoil:next_if-docs, r=jhpratt REVERT: 9c71d4ed0a3 add std::panic::abort_unwind REVERT: 91ebe065a2b add core::panic::abort_unwind REVERT: f30a0ad1f84 Merge from rustc REVERT: 24fa8b92d38 Rustfmt REVERT: 4f3d542db01 [`cfg_match`] Generalize inputs REVERT: 80f8aeb7458 Fix awkward wording. REVERT: 84d77befb81 Address WaffleLapkin's comments REVERT: 84da2fc1d77 Update tests for hidden references to mutable static REVERT: 34e22e80c1a Rollup merge of #130245 - RalfJung:miri-alloc-backtrace, r=Amanieu REVERT: ba7302270d3 Stabilize entry_insert REVERT: 283ce13a8f1 Auto merge of #130281 - matthiaskrgr:rollup-1b2ibs8, r=matthiaskrgr REVERT: ac68273ba0c Rollup merge of #130101 - RalfJung:const-cleanup, r=fee1-dead REVERT: 6695a568f5b Document subtleties of `ManuallyDrop` REVERT: 1128894f6c8 Stabilize `const_float_classify` REVERT: 0de05400c79 Auto merge of #129992 - alexcrichton:update-compiler-builtins, r=tgross35 REVERT: 553ca3f0eda also update the wrapping_ docs to use similar wording REVERT: 27049a03ee5 Rollup merge of #130160 - Scripter17:fix-slice-first_mut-doc, r=Amanieu REVERT: 03dedd99fd9 Rollup merge of #125060 - ChrisJefferson:pathbuf-doc, r=workingjubilee REVERT: abe63f65a04 simplify float::classify logic REVERT: 34e4b6d8f7e Fixup docs for PathBuf REVERT: 22ffa3d384f Expand PathBuf documentation REVERT: 4afc77fbbde Merge from rustc REVERT: 5997b68ff2a Auto merge of #130183 - Marcondiro:unicode-16.0.0, r=Manishearth REVERT: 60b4cf8f49c Rollup merge of #130248 - nyurik:fix-129895, r=workingjubilee REVERT: 136504a6163 Rollup merge of #130168 - juliusl:pr/fix-win-fs-change-time-links, r=ChrisDenton REVERT: e9cd33cba20 Rollup merge of #130077 - madsmtm:watchos-arm-unwind, r=workingjubilee REVERT: 0ff84286245 Rollup merge of #129835 - RalfJung:float-tests, r=workingjubilee REVERT: 15a8ea1b299 Rollup merge of #129696 - RalfJung:stdarch, r=Amanieu REVERT: e977a4483e4 Limit `libc::link` usage to `nto70` target only, not NTO OS REVERT: acd25269596 various updates based on review REVERT: dbf585c158e make basic allocation functions track_caller in Miri for nicer backtraces REVERT: 3e2ea2b035a chore: remove struct details REVERT: 6ff27d2d309 Rollup merge of #130207 - GrigorenkoPV:ERROR_CANT_RESOLVE_FILENAME, r=ChrisDenton REVERT: 0a476447a26 Rollup merge of #130206 - GrigorenkoPV:WSAEDQUOT, r=ChrisDenton REVERT: 61a646bcf16 Rollup merge of #129866 - root-goblin:patch-1, r=workingjubilee REVERT: bfe2669a142 docs: remove struct info REVERT: 3c00ffabf46 ptr::add/sub: these are *not* equivalent to offset(count as isize) REVERT: e8ddc864cb7 update stdarch REVERT: a55bf34b421 MaybeUninit::zeroed: mention that padding is not zeroed REVERT: 04c4ab4a2a1 clean up internal comments about float semantics REVERT: fc9b01ff3b2 these tests seem to work fine on i586 these days REVERT: 95de48b8208 Auto merge of #129403 - scottmcm:only-array-simd, r=compiler-errors REVERT: 95f9af09fc2 Clarify docs for std::collections REVERT: cc0044c5077 Map `ERROR_CANT_RESOLVE_FILENAME` to `ErrorKind::FilesystemLoop` REVERT: fde9f6bb823 Map `WSAEDQUOT` to `ErrorKind::FilesystemQuotaExceeded` REVERT: 22c4e8e02e4 Auto merge of #130025 - Urgau:missing_docs-expect, r=petrochenkov REVERT: 0eb5d756238 Bump unicode printable to version 16.0.0 REVERT: 17e1039b09f Bump unicode_data to version 16.0.0 REVERT: 4d5609fc793 Auto merge of #130179 - workingjubilee:rollup-l78cv44, r=workingjubilee REVERT: d9d37510b85 Ban non-array SIMD REVERT: 7e4cfbc077d Rollup merge of #130164 - RalfJung:const_ptr_as_ref, r=dtolnay REVERT: 3fdbce0f3f5 Rollup merge of #130146 - folkertdev:bootstrap-naked-asm, r=Amanieu REVERT: 0bbb25df201 Rollup merge of #130132 - sunshowers:illumos-sigsegv, r=Noratrieb REVERT: ec7fd8a79b5 Rollup merge of #128316 - GrigorenkoPV:io_error_a_bit_more, r=dtolnay REVERT: 237b11d4e77 Auto merge of #129778 - RalfJung:interp-lossy-typed-copy, r=saethlin REVERT: b47535f9562 chore: removing supporting links in favor of existing doc-comment style REVERT: b6f9e80a922 maint: update docs for change_time ext and doc links REVERT: f7b7aa3dce4 Rollup merge of #130154 - okaneco:stabilize_char_min, r=cuviper REVERT: 5a87e4c04c5 Rollup merge of #130067 - madsmtm:clean-up-fs-test, r=ChrisDenton REVERT: 41cd5712d57 move const fn with a null check into const_ptr_is_null gate REVERT: f28b1d1f142 move some const fn out of the const_ptr_as_ref feature REVERT: 4b1440a98ef Fix slice::first_mut docs pointer -> reference REVERT: 2bc7f6c8ae7 Stabilize `char::MIN` REVERT: d2571591f4f fix UB in a test REVERT: 931d271b035 Add missing `#[allow(missing_docs)]` on hack functions in alloc REVERT: 4f7783143b7 `RepeatN`: use MaybeUninit REVERT: 0414a2efc72 bootstrap `naked_asm!` for `compiler-builtins` REVERT: 2582bbb06c7 Rollup merge of #130115 - eduardosm:needless-returns-libs, r=workingjubilee REVERT: e8d9b858f36 Rollup merge of #130107 - RalfJung:const-ptr-is-null, r=oli-obk REVERT: 2e128a21428 Rollup merge of #130090 - RalfJung:result-copied, r=Noratrieb REVERT: 2ee8304535b Rollup merge of #130087 - RalfJung:option-const-iter, r=workingjubilee REVERT: af9a77d0661 [illumos] enable SIGSEGV handler to detect stack overflows REVERT: 1b763fc2428 remove const_slice_index annotations, it never had a feature gate anyway REVERT: 9849587e9b4 add FIXME(const-hack) REVERT: 565b336d144 move Option::unwrap_unchecked into const_option feature gate REVERT: f9a9560c597 Remove needless returns detected by clippy in libraries REVERT: cc4242b209f const: make ptr.is_null() stop execution on ambiguity REVERT: 295946c6c1a Option, Result: put the &mut variants of 'copied' under the same feature as the '&' variants REVERT: 4caabcd5cea Auto merge of #130002 - orlp:better-div-floor-ceil, r=thomcc REVERT: 55f602f895a Auto merge of #129019 - kromych:master, r=workingjubilee REVERT: 84184ab6ba4 Fix linking error when compiling for 32-bit watchOS REVERT: e954412fd46 remove pointless rustc_const_unstable on trait impls REVERT: 0dc4621c3ac add some FIXME(const-hack) REVERT: 796ae33b0c9 Auto merge of #130091 - matthiaskrgr:rollup-kalu1cs, r=matthiaskrgr REVERT: 64afc032b5d Rollup merge of #130047 - ChrisDenton:win-dbghelp, r=wesleywiser REVERT: 944866225f4 Rollup merge of #130046 - RalfJung:const_str_as_mut, r=dtolnay REVERT: 2feca1e6134 Rollup merge of #129555 - RalfJung:const_float_bits_conv, r=dtolnay REVERT: 4f47132d7d3 Auto merge of #129941 - BoxyUwU:bump-boostrap, r=albertlarsan68 REVERT: 72723d7cc0d make Result::copied unstably const REVERT: 50116718108 remove 'const' from 'Option::iter' REVERT: 3a535378088 str: make as_mut_ptr and as_bytes_mut unstably const REVERT: 9469575a168 restate GlobalAlloc method safety preconditions in terms of what the caller has to do for greater clarity REVERT: ff7b66117b7 Remove now redundant check in symlink_hard_link test REVERT: 459f246405d Add `NonNull` convenience methods to `Vec` REVERT: a2e7f8b53ee Add `NonNull` convenience methods to `Box` REVERT: d1005f501ee fix doc comments for Peekable::next_if(_eq) REVERT: a9cf084c94a Remove duplicate impl REVERT: 7b61eea4f31 remove the Clone requirement REVERT: d6e859b240e Win: Add dbghelp to the list of import libraries REVERT: 335236cb011 properly handle EOF in BufReader::peek REVERT: b2d6fdd4d85 [library/std/src/process.rs] Remove `Eq` `derive` REVERT: fd0bc94d539 Adjust doc comment of Condvar::wait_while REVERT: 2699de648cc Rollup merge of #129963 - rjooske:fix/inaccurate_to_string_lossy_doc, r=workingjubilee REVERT: cde81452601 Auto merge of #129999 - matthiaskrgr:rollup-pzr9c8p, r=matthiaskrgr REVERT: 678165efe80 Break into the debugger (if attached) on panics (Windows, macOS, Linux, FreeBSD) REVERT: b947f0a81ef better implementation of signed div_floor/ceil REVERT: ab4b4f8c12e Rollup merge of #129947 - LiterallyVoid:duration-docs-digit-separators, r=tgross35 REVERT: 3e7e6cdbd64 Rollup merge of #129653 - RalfJung:addr-of-read-only, r=scottmcm REVERT: e51a0bc9ea0 Rollup merge of #129938 - chancancode:patch-1, r=thomcc REVERT: 355445b0261 [library/std/src/process.rs] Update docstring with @joshtriplett's replacement text REVERT: 0d4a80eaee3 Update compiler-builtins to 0.1.125 REVERT: 349f8d57256 update cfgs REVERT: 181dc2674a5 Rollup merge of #129919 - kevinmehall:waker-getters, r=dtolnay REVERT: 3d2a91f59a9 Rollup merge of #127021 - thesummer:1-add-target-support-for-rtems-arm-xilinx-zedboard, r=tgross35 REVERT: 25891c8560a Rollup merge of #101339 - the8472:ci-randomize-debug, r=Mark-Simulacrum REVERT: 5446229e7af Use non-overlapping swap for inner heapsort loop REVERT: 670630da181 Select tiny sorts for 16-bit platforms REVERT: cd3d6e88bc9 Shrink heapsort further by combining sift_down loops REVERT: bea61dafef2 Drop bubble_sort REVERT: eb4746892bf fix: correct {Path,OsStr}::to_string_lossy() docs REVERT: 83938b9ae3d Remove macOS 10.10 dynamic linker bug workaround REVERT: 76972316fb6 docs: add digit separators in `Duration` examples REVERT: 9ed92df9886 replace placeholder version REVERT: 00e12f791e4 Update marker.rs REVERT: 5de059ff2d0 Update marker.rs REVERT: 72e79f0c1de Update marker.rs REVERT: 870dfeddde9 Update marker.rs REVERT: de72cd33be9 Elaborate on deriving vs implementing `Copy` REVERT: be2b964527c Win: Open dir for sync access in remove_dir_all REVERT: fee63007a49 More robust extension checking REVERT: ae90e450fd9 Port std library to RTEMS REVERT: c313c072ba2 Rollup merge of #129916 - tshepang:basic-usage, r=ChrisDenton REVERT: c501959a497 Rollup merge of #129913 - saethlin:l4re-read-buf, r=Noratrieb REVERT: 83524b98e8b Rollup merge of #129885 - cuishuang:master, r=scottmcm REVERT: e41afdc2cc8 Rollup merge of #129800 - ChrisDenton:remove-dir-all2, r=Amanieu REVERT: 851f5b63258 Add `Waker::new` and `LocalWaker::new` REVERT: a2b8bb8baae Stabilize waker_getters REVERT: 2ec266b2cd4 Move the `data` and `vtable` methods from `RawWaker` to `Waker` REVERT: 562fdcec802 process.rs: remove "Basic usage" text where not useful REVERT: 9b3c3fecc0d Rollup merge of #129907 - saethlin:solid-io-error, r=WaffleLapkin REVERT: 02cecebd3a9 Rollup merge of #129892 - oskgo:clarify-slice-from-raw, r=RalfJung REVERT: ccc294c2a53 Rollup merge of #129890 - alex:patch-1, r=workingjubilee REVERT: 6d0e687304b Rollup merge of #129856 - RalfJung:compiler_fence, r=thomcc REVERT: 0ccc851a07e Rollup merge of #129748 - RalfJung:box-validity, r=workingjubilee REVERT: 37618495ad7 Add missing read_buf stub for x86_64-unknown-l5re-uclibc REVERT: 3b8ab5a6439 Fix compile error in solid's remove_dir_all REVERT: e14b9f387e8 clarify language around non-null ptrs in slice::raw REVERT: 9a76abd8364 Remove stray word in a comment REVERT: 1dd630f2324 Auto merge of #129873 - matthiaskrgr:rollup-bv849ud, r=matthiaskrgr REVERT: 26498824037 chore: remove repetitive words REVERT: 7fd784ec2ba Rollup merge of #129804 - ranger-ross:fixed-documentation-typos, r=Noratrieb REVERT: e4e9f6b9248 Rollup merge of #129793 - lolbinarycat:doc-missing-newlines, r=workingjubilee REVERT: c4aa66aca88 Auto merge of #129063 - the8472:cold-opt-size, r=Amanieu REVERT: 4e3dbeedf82 add extra linebreaks so rustdoc can identify the first sentence REVERT: e00784f5e85 compiler_fence documentation: emphasize synchronization, not reordering REVERT: a4c4e236c17 stabilize const_float_bits_conv REVERT: 8d8dbe91b02 tweak wording regarding Box validity REVERT: 065844bb5f0 Auto merge of #127897 - nyurik:add-qnx-70-target, r=saethlin REVERT: 759399be7a3 Rollup merge of #129832 - eduardosm:stray-dot, r=jhpratt REVERT: 60f37e4ad71 Rollup merge of #129207 - GrigorenkoPV:elided-is-named, r=cjgillot REVERT: 68e6537ba28 Rollup merge of #128641 - Konippi:standardize-duplicate-processes-in-parser, r=scottmcm REVERT: b93e3abbf07 Rollup merge of #128495 - joboet:more_memcmp, r=scottmcm REVERT: 64c1db22d08 when -Zrandomize-layout is enabled disable alloc test testing internal struct sizes REVERT: d432698157c Auto merge of #129831 - matthiaskrgr:rollup-befq6zx, r=matthiaskrgr REVERT: 77cf0ba112b Remove stray dot in `std::char::from_u32_unchecked` documentation REVERT: ef033b028ed Rollup merge of #129826 - Alcaro:patch-1, r=workingjubilee REVERT: 2ad03e02998 Rollup merge of #129650 - Zalathar:profiler-builtins, r=Mark-Simulacrum REVERT: c33b3dfa8ec Update mod.rs REVERT: 24ed1c124d6 Rollup merge of #129785 - RalfJung:miri-sync, r=RalfJung REVERT: 50681ab44e8 Rollup merge of #129730 - RalfJung:float-arithmetic, r=workingjubilee REVERT: 0402bb10c5a Fix `elided_named_lifetimes` in code REVERT: 3a754b1b94e Improve documentation for ::from_str_radix REVERT: 667d060bfd6 Move remove_dir_all impl into a module REVERT: ae18edf95f4 Rollup merge of #129754 - alexcrichton:fix-wasi-long-sleep, r=workingjubilee REVERT: 9138bd188f5 Rollup merge of #129675 - lolbinarycat:bufreader_peek_unsized, r=workingjubilee REVERT: 83cadd0fe20 Rollup merge of #129642 - workingjubilee:bump-backtrace-fc37b22, r=workingjubilee REVERT: d9af971403a Rollup merge of #129640 - saethlin:unignore-android-in-alloc, r=tgross35 REVERT: 6b12a632e1d Fixed more typos in library/core REVERT: 40f9251a0cd Fixed typos in btree map docs REVERT: 628be3dae28 Fixed some typos in the standard library documentation/comments REVERT: 21e893e6b6d enumerate the two parts of the NaN rules REVERT: 081353cd333 add hyphen in floating-point REVERT: c664843f3b7 Squashed `aarch64_unknown_nto_qnx700` support REVERT: 5c4c81a7c61 Merge from rustc REVERT: 24eca285951 add new_cyclic_in for Arc REVERT: 88d85a8c068 improve comments REVERT: 3e677e3f79a fix new_cyclic_in for rc REVERT: 7d4ef1728c0 fix fmt REVERT: a37464739a6 Try latest backtrace REVERT: 2c75dd81561 wasi: Fix sleeping for `Duration::MAX` REVERT: 374229a0231 Rollup merge of #128166 - ChaiTRex:isqrt, r=tgross35 REVERT: f0dce767de0 Rollup merge of #123940 - kornelski:remove-derived-debug, r=Urgau REVERT: 228ec9e62ac Box validity: update for new zero-sized rules REVERT: 717e3aa5f1f Use simpler branchy swap logic in tiny merge sort REVERT: 93a72daf8ad f32 docs: define 'arithmetic' operations REVERT: 1bc188fd531 Merge from rustc REVERT: c44af617f84 Speed up `checked_isqrt` and `isqrt` methods REVERT: 21396512b94 Improve `isqrt` tests and add benchmarks REVERT: 7c1560f9833 Rollup merge of #129715 - Amjad50:update-compiler-builtins, r=tgross35 REVERT: d2a001df590 Rollup merge of #129683 - RalfJung:copysign, r=thomcc REVERT: 8753a357ece Rollup merge of #129673 - matthewpipie:arc-weak-debug-trait, r=dtolnay REVERT: 3e1f63a7ab6 Rollup merge of #129401 - workingjubilee:partial-initialization-of-stabilization, r=dtolnay,joboet REVERT: cd59153e222 Rollup merge of #129378 - goffrie:patch-3, r=ChrisDenton REVERT: 6d31b6de716 Rollup merge of #128192 - mrkajetanp:feature-detect, r=Amanieu REVERT: 5fa71afdd50 add guarantee about remove_dir and remove_file error kinds REVERT: 60fd9c980c3 Update `compiler_builtins` to `0.1.123` REVERT: 86c924ff3e5 fmt-debug option REVERT: 8623fa49bac allow BufReader::peek to be called on unsized types REVERT: b1a56b508b6 Auto merge of #129691 - matthiaskrgr:rollup-owlcr3m, r=matthiaskrgr REVERT: 39ad6a926e3 Rollup merge of #129668 - coolreader18:fix-pin-set-regr, r=dtolnay REVERT: 5a4fe4044d8 Rollup merge of #129657 - jswrenn:transmute-name, r=compiler-errors REVERT: 1d44fabf570 Rollup merge of #129551 - RalfJung:ub-checks-fallback, r=saethlin REVERT: b0fee9815c8 Rollup merge of #129480 - lolbinarycat:euclid-docs, r=joboet REVERT: c8d3265d52d Enable some ilog2 tests as well REVERT: da08ef4ef5a Re-enable android tests/benches in alloc REVERT: bfbe13e1767 Auto merge of #129589 - saethlin:improve-panic-immediate-abort, r=tgross35 REVERT: 89021c809f8 copysign with sign being a NaN is non-portable REVERT: ed66a11c68e addr_of on places derived from raw pointers should preserve permissions REVERT: ea236f07aef add new_cyclic_in for rc REVERT: 17298981159 Add fmt::Debug to sync::Weak REVERT: 927a6da67ab Fix Pin::set bounds regression REVERT: 9876bd1014d library: Stabilize new_uninit for Box, Rc, and Arc REVERT: a0ea69f6e4e Rollup merge of #129652 - RalfJung:ptr-to-ref, r=traviscross REVERT: c7cbb41d48c Rollup merge of #129645 - beetrees:fix-float-docs, r=tgross35 REVERT: 04eabb59f6a Rollup merge of #129581 - RalfJung:exit, r=joshtriplett REVERT: 33e2d7e8de6 safe transmute: Rename `BikeshedIntrinsicFrom` to `TransmuteFrom` REVERT: 72c676f1fdb Auto merge of #128134 - joboet:move_pal_alloc, r=cupiver REVERT: c108af0dbf3 fix Pointer to reference conversion docs REVERT: 193310350fc clarify that addr_of creates read-only pointers REVERT: 4f6b8149292 rustc_target: Add SME aarch64 features REVERT: 012bb44c6c5 rustc_target: Add various aarch64 features REVERT: 4dc5b675267 std: move allocators to `sys` REVERT: ae57bdf05e4 Use last swap optimization in bubblesort REVERT: 264fa88ed6a Don't skip nonexistent source files REVERT: 5298b521b75 Add `cargo::rerun-if-changed` directives for source directories REVERT: 5defa797459 Always include `WindowsMMap.c` in the list of source files REVERT: 91d2ecf1eca Sort the list of source files REVERT: cb468d737ba Remove `InstrProfilingBiasVar.c` from the list of source files REVERT: 0e0134f5d4b Use helper functions to read environment variables REVERT: a628540ba41 Rollup merge of #129559 - RalfJung:float-nan-semantics, r=thomcc REVERT: 00c8f98e15e Rollup merge of #128731 - RalfJung:simd-shuffle-vector, r=workingjubilee REVERT: 6d3344f0919 Update old comment referring to `libcompiler_builtins` REVERT: 6d8a1f6903e Reflow a couple of paragraphs in floating-point primitive docs REVERT: 8834d35fa4b Fix typos in floating-point primitive type docs REVERT: 54c986a8287 Bump backtrace to rust-lang/backtrace@fc37b22 REVERT: 932cbd42f14 Rollup merge of #129032 - jswrenn:transmute-method, r=compiler-errors REVERT: 28a983de9a8 Rollup merge of #128157 - lolbinarycat:unify-ptr-ref-docs, r=cuviper REVERT: d1e21bdba8d Apply suggestions from code review REVERT: febaf22f00e Rollup merge of #129592 - saethlin:core-cfg-test, r=tgross35 REVERT: 77a1318f7f7 Rollup merge of #129588 - hermit-os:sleep-micros, r=workingjubilee REVERT: 12fe23bd5dc Rollup merge of #129539 - oconnor663:poll_link, r=tgross35 REVERT: 864e465be7b Rollup merge of #129377 - chorman0773:unbounded-shifts-impl, r=scottmcm REVERT: 07cfc6ae040 also update copysign docs REVERT: acaef605e72 move per-target NaN info into a table REVERT: 854ba7e4cef float types: document NaN bit pattern guarantees REVERT: 2fa330eeddd Convert cfg blocks to cfg_if REVERT: f46fcfed644 Reduce code duplication by moving partition_lomuto_branchless_simple into quicksort module REVERT: d958260763a Auto merge of #129595 - matthiaskrgr:rollup-4udn7nn, r=matthiaskrgr REVERT: 8dd3363de6a Remove cfg(test) from library/core REVERT: cd554e2b4ea Rollup merge of #129544 - mu001999-contrib:dead-code/clean, r=compiler-errors REVERT: ff769eef88a Rollup merge of #129525 - notriddle:notriddle/fake-variadic-tuple-array, r=GuillaumeGomez REVERT: 4d22c1c6b37 Auto merge of #129488 - saethlin:alignment-precondition, r=workingjubilee REVERT: c688deff96a pal/hermit: saturate `usleep` microseconds at `u64::MAX` REVERT: 8ea71ae5647 Auto merge of #129563 - matthiaskrgr:rollup-t6bai2d, r=matthiaskrgr REVERT: 46eff207f56 Tweak some attributes to improve panic_immediate_abort REVERT: fdb5fc1fca6 pal/hermit: correctly round up microseconds in `Thread::sleep` REVERT: 1805c29ca12 Add binary-size optimized variants for stable and unstable sort as well as select_nth_unstable REVERT: b392703506b exit: explain our expectations for the exit handlers registered in a Rust program REVERT: 22ec8977a9a link to Future::poll from the Poll docs REVERT: a994fbbca83 Rollup merge of #129487 - GrigorenkoPV:repr_transparent_external_private_fields, r=compiler-errors REVERT: 3a339226a95 Rollup merge of #129416 - workingjubilee:partial-move-from-stabilization, r=dtolnay REVERT: 3a8de952989 Rollup merge of #129091 - RalfJung:box_as_ptr, r=Amanieu REVERT: 4de4debd1eb Auto merge of #129295 - Zalathar:profiler-builtins, r=Kobzol REVERT: 0872cf30408 ub_checks intrinsics: fall back to cfg(ub_checks) REVERT: 8dafd337e12 Auto merge of #129521 - matthiaskrgr:rollup-uigv77m, r=matthiaskrgr REVERT: d9e489b48ce Removes dead code from the compiler REVERT: c14cf57e404 Rollup merge of #129481 - scottmcm:update-cb, r=tgross35 REVERT: acf6f03b6fa Rollup merge of #129449 - coolreader18:pin-as_deref_mut-signature, r=dtolnay REVERT: 112ebc4d5a9 Rollup merge of #128735 - jieyouxu:pr-120176-revive, r=cjgillot REVERT: 49aa496c5bb rustdoc: clean up tuple <-> primitive conversion docs REVERT: 0fe374666ac Rollup merge of #129501 - RalfJung:miri-rust-backtrace, r=Noratrieb REVERT: 7d5cf38931b Rollup merge of #129500 - fee1-dead-contrib:fxrel, r=compiler-errors REVERT: e91d825f826 Rollup merge of #129323 - Urgau:ptr_fn_addr_eq, r=Mark-Simulacrum REVERT: f6470795864 Rollup merge of #128596 - RalfJung:const_fn_floating_point_arithmetic, r=nnethercote REVERT: f965950f05e New `#[rustc_pub_transparent]` attribute REVERT: a6ea125cb0e panicking: improve hint for Miri's RUST_BACKTRACE behavior REVERT: a437005e6f3 Build `library/profiler_builtins` from `ci-llvm` if appropriate REVERT: 693477a3f65 remove invalid `TyCompat` relation for effects REVERT: 82fc74f6f1a library: Move unstable API of new_uninit to new features REVERT: 4bc6b1fd2a5 Pass `fmt::Arguments` by reference to `PanicInfo` and `PanicMessage` REVERT: 3ee2e18c8dc Enable Alignment::new_unchecked precondition check REVERT: 0803686e7fb Change `f16` doctests in core to run on x86-64 linux REVERT: 9359a126d41 Update `compiler_builtins` to `0.1.121` REVERT: da02e8b5609 Enable `f16` tests on x86 and x86-64 REVERT: f3a198e85be docs: correct panic conditions for rem_euclid and similar functions REVERT: 976fb4aeefc Move into_inner_unchecked back to the bottom of the impl block REVERT: 2741e8dacb4 Put Pin::as_deref_mut in impl Pin REVERT: 88790f80130 document & impl the transmutation modeled by `BikeshedIntrinsicFrom` REVERT: f670207d0f4 Auto merge of #129464 - GuillaumeGomez:rollup-ckfqd7h, r=GuillaumeGomez REVERT: 5bf661cc64f Rollup merge of #129276 - eduardosm:stabilize-char_indices_offset, r=Amanieu REVERT: e2614f24b27 Rollup merge of #129400 - Amjad50:update-compiler-builtins, r=tgross35 REVERT: 2c06146be10 Rollup merge of #127623 - lolbinarycat:fix_remove_dir_all, r=Amanieu REVERT: 1339c1bf0a9 Implement feature `string_from_utf8_lossy_owned` REVERT: eb747e53dd0 Check that `library/profiler_builtins` actually found some source files REVERT: eae79872269 fix typos in new pointer conversion docs REVERT: fe33d2c256c fix: fs::remove_dir_all: treat ENOENT as success REVERT: 3fd591ebdef feat(core): Make `unbounded_shl{l,r}` unstably const and remove `rustc_allow_const_fn_unstable` REVERT: 2168ce32967 Auto merge of #129398 - matthiaskrgr:rollup-50l01ry, r=matthiaskrgr REVERT: 12944c76047 Update `compiler_builtins` to `0.1.120` REVERT: 7496478b7a5 stabilize const_fn_floating_point_arithmetic REVERT: 6f534f94217 Rollup merge of #129382 - tgross35:once-cell-const-into-inner, r=Noratrieb REVERT: 2535017098e Rollup merge of #129376 - ChaiTRex:assert_unsafe_precondition_check_language_ub, r=workingjubilee,the8472 REVERT: 4ec19afe669 Rollup merge of #129374 - ChaiTRex:digit_unchecked_assert_unsafe_precondition, r=scottmcm REVERT: 024ec3c0f62 Rollup merge of #128432 - g0djan:godjan/wasi_prohibit_implicit_unsafe, r=tgross35 REVERT: f671c1129b9 Auto merge of #129365 - matthiaskrgr:rollup-ebwx6ya, r=matthiaskrgr REVERT: 5299ef149b1 fix(core): Use correct operations/values in `unbounded_shr` doctests REVERT: 84230062104 chore: `x fmt` REVERT: cbe7338e1f3 fix(core): Add `#![feature(unbounded_shifts)]` to doctests for `unbounded_shr`/`unbounded_shl` REVERT: 863123bd7c4 Add `const_cell_into_inner` to `OnceCell` REVERT: b51f35e9d47 format REVERT: 6fd539327d2 chore: `x fmt` and hopefully fix the tidy issue REVERT: e99c681c95b Clean up cfg-gating of ProcessPrng extern REVERT: 9d2bb976994 Change `assert_unsafe_precondition` docs to refer to `check_language_ub` REVERT: 32bd5dfb369 chore: Also format the control flow REVERT: 5f8cf71d7d6 Manually format functions and use `rhs` instead of `v` from my CE testing REVERT: 700af565751 feat(core): Add implementations for `unbounded_shl`/`unbounded_shr` REVERT: a9ad57eb6a1 Use `assert_unsafe_precondition!` in `AsciiChar::digit_unchecked` REVERT: 77bd65fdedc Rollup merge of #129321 - krtab:float_sum, r=workingjubilee REVERT: cc219788b51 Rollup merge of #129232 - ivmarkov:master, r=workingjubilee REVERT: c9cf844ccd3 Rollup merge of #127945 - tgross35:debug-more-non-exhaustive, r=Noratrieb REVERT: d37ebfea900 Rollup merge of #129332 - cuviper:cstr-cast, r=compiler-errors REVERT: 6d01ed8b3bd Rollup merge of #129312 - tbu-:pr_str_not_impl_error, r=Noratrieb REVERT: 93319c80754 Fix stability attribute of `impl !Error for &str` REVERT: 7f8bdd574b6 Auto merge of #126556 - saethlin:layout-precondition, r=joboet REVERT: 9e9141f54eb Auto merge of #128866 - scottmcm:update-stdarch, r=tgross35 REVERT: d47cfba89b7 Update stdarch submodule REVERT: b507a8bfeb9 Try to golf down the amount of code in Layout REVERT: 32b574e848f Avoid extra `cast()`s after `CStr::as_ptr()` REVERT: 9d4113ff24d Rollup merge of #129294 - scottmcm:stabilize-repeat-n, r=Noratrieb REVERT: 62d240d9b6a Implement `ptr::fn_addr_eq` REVERT: 529e33acb80 Change neutral element of to neg_zero REVERT: 126935f7257 Stabilize `iter::repeat_n` REVERT: 91439ce7b58 Auto merge of #129226 - RalfJung:libc, r=Mark-Simulacrum REVERT: bef7be0e71e Add a precondition check for Layout::from_size_align_unchecked REVERT: a55ab85ad47 Stabilize feature `char_indices_offset` REVERT: 7f45dcfa195 library: bump libc dependency REVERT: ebe99f3b8b6 Rollup merge of #128902 - evanj:evan.jones/env-var-doc, r=workingjubilee REVERT: 9b21aa05574 Document futility of printing temporary pointers REVERT: 8bdd95ba4da soft-deprecate the addr_of macros REVERT: 23b0aadc2ce code review improvements REVERT: 0b0dad4af6f Fix for issue #129212 for the ESP-IDF REVERT: bd7aa576572 Auto merge of #126877 - GrigorenkoPV:clone_to_uninit, r=dtolnay REVERT: d3c08f8f8ac Auto merge of #128598 - RalfJung:float-comments, r=workingjubilee REVERT: dc5fed53253 Auto merge of #106943 - mina86:exact_size_take_repeat, r=dtolnay REVERT: 88927ac26eb Auto merge of #116528 - daxpedda:stabilize-ready-into-inner, r=dtolnay REVERT: 9952947d86b Rollup merge of #129161 - dtolnay:spawnunck, r=Noratrieb REVERT: db3abec9727 Rollup merge of #129086 - slanterns:is_none_or, r=dtolnay REVERT: 44a558dc7dc Stabilize std::thread::Builder::spawn_unchecked REVERT: 028104e3bde Refer to other docs REVERT: 5c553c41134 float to/from bits and classify: update comments regarding non-conformant hardware REVERT: 9704e2df60c Rollup merge of #128064 - ijackson:noop-waker-doc, r=workingjubilee REVERT: 0497f0c6c91 Add cautionary paragraph about noop wakers. REVERT: e0fe4a7ca28 Add unordered list with possible values for each const REVERT: 84ea721e3d5 Format std::env::consts docstrings REVERT: 16dd42669a2 Rollup merge of #128946 - orlp:faster-ip-hash, r=joboet REVERT: 383c4db14b0 Rollup merge of #128925 - dingxiangfei2009:smart-ptr-helper-attr, r=compiler-errors REVERT: ba3a942d5de Rollup merge of #125970 - RalfJung:before_exec, r=m-ou-se REVERT: 32a71bb1dc7 size-optimize some of the panic dependencies REVERT: d7b85f24937 apply #[optimize(size)] to #[cold] ones and part of the panick machinery REVERT: 0dbf8cff9de Rollup merge of #128954 - zachs18:fromresidual-no-default, r=scottmcm REVERT: 4f0959927f2 Rollup merge of #128570 - folkertdev:stabilize-asm-const, r=Amanieu REVERT: b6c9e44d2a6 add Box::as_ptr and Box::as_mut_ptr methods REVERT: 23d1309b02e CommandExt::before_exec: deprecate safety in edition 2024 REVERT: 7921401d1ae stabilize `option_get_or_insert_default` REVERT: 9858d49b168 stabilize `is_none_or` REVERT: fd2b339c5a6 Auto merge of #129060 - matthiaskrgr:rollup-s72gpif, r=matthiaskrgr REVERT: 3b8aab7df81 Rollup merge of #129001 - cblh:fix/128713, r=Noratrieb REVERT: 16edf695130 Rollup merge of #128873 - ChrisDenton:windows-targets, r=Mark-Simulacrum REVERT: 0199b00c91f Rollup merge of #128759 - notriddle:notriddle/spec-to-string, r=workingjubilee,compiler-errors REVERT: c370665e88b Make `std::os::darwin` public REVERT: c6dc243b917 stabilize `asm_const` REVERT: b4bfc215048 Rollup merge of #129034 - henryksloan:coroutine-must-use, r=joboet REVERT: b56fdcb2730 Rollup merge of #127857 - tbu-:pr_deprecated_safe_todo, r=petrochenkov REVERT: 77f462da866 Rollup merge of #122884 - mzabaluev:pow-remove-exit-branch, r=Amanieu REVERT: 0a6a74bce1a Reduce merged doctest source code size REVERT: a83dde61642 Mark location doctest as standalone since file information will not work in merged doctest file REVERT: 7334c7178ce Auto merge of #129046 - matthiaskrgr:rollup-9x4xgak, r=matthiaskrgr REVERT: 9ed72103664 Rollup merge of #128745 - dtolnay:spawnunchecked, r=workingjubilee REVERT: c39d90e4d51 Rollup merge of #128655 - joboet:play_with_the_dice, r=ChrisDenton REVERT: f81c96a863e `#[deprecated_safe_2024]`: Also use the `// TODO:` hint in the compiler error REVERT: 23a19685c9b Allow to customize `// TODO:` comment for deprecated safe autofix REVERT: 37017c0f6f6 Auto merge of #128962 - devnexen:fs_get_mode_haiku, r=workingjubilee REVERT: 6ad03a7161f simd_shuffle intrinsic: allow argument to be passed as vector (not just as array) REVERT: 8a2671a2889 Revert to original loop for const pow exponents REVERT: c5e81895dfb Auto merge of #128742 - RalfJung:miri-vtable-uniqueness, r=saethlin REVERT: ac682f19873 Add must_use attribute to Coroutine trait REVERT: 658904d1a9a chore(lib): fmt core::fmt::Formatter's write_fmt method REVERT: 7eb73762bb3 trying common codepath for every unixes REVERT: 5fabf93c765 std::fs: get_mode implementation for haiku. REVERT: e3da824e62c Rollup merge of #129017 - its-the-shrimp:core_fmt_from_fn, r=Noratrieb REVERT: b247d9a7a9a derive(SmartPointer): register helper attributes REVERT: aa854485cea Explicitly specify type parameter on FromResidual impls in stdlib. REVERT: 262a4f6b641 std::fmt::FormatterFn -> std::fmt::FromFn REVERT: ceceae30ced Rollup merge of #128632 - joboet:dont_overwrite_style, r=Amanieu REVERT: e8f7afeb117 Rollup merge of #128149 - RalfJung:nontemporal_store, r=jieyouxu,Amanieu,Jubilee REVERT: 7dd208356e1 chore(lib): Enhance documentation for core::fmt::Formatter's write_fmt method REVERT: 048efd0bcec ignore some vtable/fn ptr equality tests in Miri, their result is not fully predictable REVERT: a367a12df0a std: use `/scheme/rand` on Redox REVERT: 4b816b496d5 core: make documentation clearer, rename slice comparison specialization trait REVERT: 1ca6b42583f std: do not overwrite style in `get_backtrace_style` REVERT: 91477777de1 Auto merge of #128862 - cblh:fix/128855, r=scottmcm REVERT: 56e1afe0810 Auto merge of #126793 - saethlin:mono-rawvec, r=scottmcm REVERT: ec7a585087c Do not use unnecessary endian conversion. REVERT: f48facfed72 Rollup merge of #128882 - RalfJung:local-waker-will-wake, r=cuviper REVERT: b581949746c Rollup merge of #120314 - mina86:i, r=Mark-Simulacrum REVERT: 451feca66ac Fix stability annotation and expand comment REVERT: 2e34ac388e0 Hash Ipv*Addr as an integer REVERT: b8b61e1e931 Auto merge of #128927 - GuillaumeGomez:rollup-ei2lr0f, r=GuillaumeGomez REVERT: 44f5b4fe515 Rollup merge of #128273 - Voultapher:improve-ord-violation-help, r=workingjubilee REVERT: 3d7afa0e721 Update std and compiler REVERT: 971df1c2948 Stabilize `min_exhaustive_patterns` REVERT: c37c6665b9b Add an optimizer hint for the capacity that with_capacity_in returns REVERT: c8cbd5c499c Hoist IS_ZST check out of RawVecInner::from_*_in REVERT: e843f7103a0 Polymorphize RawVec REVERT: dc39cbf9234 core: optimise Debug impl for ascii::Char REVERT: 9668691af5d doc: std::env::var: Returns None for names with '=' or NUL byte REVERT: 5d5d8bc73a9 Rollup merge of #128859 - MinxuanZ:mips-sig, r=Amanieu REVERT: 825def017bc Rollup merge of #128817 - biabbas:vxworks_update, r=tgross35 REVERT: 6e933a82c90 make LocalWaker::will_wake consistent with Waker::will_wake REVERT: 118c71296c8 Fix linkchecker issue REVERT: b1460b93704 Exclude windows-targets from the workspace REVERT: a3a6a9856c2 Add windows-targets crate to std's sysroot REVERT: f74940d94c2 Rollup merge of #128824 - GuillaumeGomez:update-compiler-builtins, r=Amanieu REVERT: 39b1eafc08c VxWorks: Add safety comment for vxCpuEnabledGet REVERT: 8b0a25df983 fix: Ensure `Guard`'s `drop` method is removed at `opt-level=s` for `Copy` types REVERT: c54958c5dad delete space REVERT: dadbd585cb3 fix format REVERT: 7c34ebf93de [SPARC] fix the name of signal 19 in sparc arch REVERT: b75648a7515 [MIPS] fix the name of signal 19 in mips REVERT: 3840b09aae3 Rollup merge of #128818 - RalfJung:std-miri-floats, r=tgross35 REVERT: d03bb5e33a9 Rollup merge of #128640 - RalfJung:rwlock-macos-miri, r=joboet REVERT: 7680a3c7598 Rollup merge of #128749 - tgross35:float-inline, r=scottmcm REVERT: 9df61adfaa1 Rollup merge of #128306 - WiktorPrzetacznik:WiktorPrzetacznik-nonnull-alignoffset-update, r=Amanieu REVERT: 39860ad52d1 Update compiler-builtins version to 0.1.118 REVERT: 42811859e46 std float tests: special-case Miri in feature detection REVERT: 4d6b36adfe6 Vxworks: Extern taskNameSet and fix build errors REVERT: e24a6ca11fa rwlock: disable 'frob' test in Miri on macOS REVERT: c21ba971a8a Fix VxWorks available parallelism: Move nonzero::uncheked into unsafe block REVERT: 249541802ec Rollup merge of #128800 - clarfonthey:core-pattern-type, r=compiler-errors REVERT: 79cd72af482 Rollup merge of #128691 - tgross35:update-builtins, r=Amanieu REVERT: 8f840157d66 Add tracking issue to core-pattern-type REVERT: b8f7f384f75 Stabilize `Ready::into_inner()` REVERT: 62ccdeb315d Rollup merge of #128261 - clarfonthey:iter-default, r=dtolnay REVERT: b4e53303f07 alloc: make `to_string_str!` a bit less complex REVERT: ec74467d64c Mark `{f32,f64}::{next_up,next_down,midpoint}` inline REVERT: b90a026d6f8 Rollup merge of #128766 - Monadic-Cat:patch-1, r=tgross35 REVERT: 5d7906c0270 Rollup merge of #128417 - tgross35:f16-f128-math, r=dtolnay REVERT: 83d1d167737 Trivial grammar fix in const keyword docs REVERT: 97384fa701b Update `compiler-builtins` to 0.1.117 REVERT: 6dc79bb6235 Rollup merge of #128751 - devnexen:vxworks_set_thread_name, r=tgross35 REVERT: 432425d28f7 Rollup merge of #128539 - biabbas:deny_unsafe, r=workingjubilee REVERT: 1bd5338eadf Rollup merge of #128406 - lolbinarycat:bufreader_peek, r=Mark-Simulacrum REVERT: e20aa6430f1 Rollup merge of #125048 - dingxiangfei2009:stable-deref, r=amanieu REVERT: bc13c6ca57a alloc: add ToString specialization for `&&str` REVERT: 14fe723f6b9 std::thread: set_name implementation proposal for vxWorks. REVERT: 67fa603356d Remove unused lifetime parameter from spawn_unchecked REVERT: 4a3da122172 Add a special case for CStr/CString in the improper_ctypes lint REVERT: 51ec2bb7ea2 implement BufReader::peek REVERT: 9cc3bc6add3 custom MIR: add support for tail calls REVERT: e6aede2233f nontemporal_store: make sure that the intrinsic is truly just a hint REVERT: a300df74d13 WASI fixing unsafe_op_in_unsafe_fn for std::{os, sys} REVERT: 5674d1c07e5 Auto merge of #128673 - matthiaskrgr:rollup-gtvpkm7, r=matthiaskrgr REVERT: deb1d7576df Rollup merge of #128619 - glandium:last_chunk, r=scottmcm REVERT: 6449537a625 Rollup merge of #128609 - swenson:smaller-faster-dragon, r=Amanieu REVERT: acb2c303c36 Rollup merge of #128026 - devnexen:available_parallelism_vxworks, r=Mark-Simulacrum REVERT: 89fe6dfa6b9 Rollup merge of #128309 - kmicklas:btreeset-cursor, r=Amanieu REVERT: 313484bb62c Correct the const stabilization of `<[T]>::last_chunk` REVERT: 22e026b048c Auto merge of #128534 - bjorn3:split_stdlib_workspace, r=Mark-Simulacrum REVERT: 59436fcc0b1 std: refactor UNIX random data generation REVERT: 8fe1e328a17 refactor: standardize duplicate processes in parser REVERT: 18136032131 Rollup merge of #128526 - tshepang:patch-1, r=Amanieu REVERT: e8a1a4151ee Auto merge of #128466 - sayantn:stdarch-update, r=tgross35 REVERT: 2adf9da42a3 Update stdarch REVERT: dc85bdb60ce Chore: add `x86_amx_intrinsics` feature flag to `core/lib.rs` and remove `issue-120720-reduce-nan.rs` REVERT: e88b04d135d Rollup merge of #128551 - Konippi:refactor-backtrace-style-in-panic, r=tgross35 REVERT: 43a1e939ebe Rollup merge of #128530 - scottmcm:repeat-n-unchecked, r=joboet REVERT: 47df194eec6 Remove unnecessary constants from flt2dec dragon REVERT: 6fafc6b5d92 Apply review comments to PartialOrd section REVERT: 0b5f1b8406f Auto merge of #128404 - compiler-errors:revert-dead-code-changes, r=pnkfelix REVERT: 35cd95f1edb Suppress new false-negatives that were masked by dead code analysis changes REVERT: 9eb9fa6d7db Revert "Rollup merge of #127107 - mu001999-contrib:dead/enhance-2, r=pnkfelix" REVERT: 975dc19795e Rollup merge of #128368 - nnethercote:rustfmt-tweaks, r=cuviper REVERT: 0ee09fe87cf Rollup merge of #128303 - NobodyXu:specialise-for-pipe, r=cuviper REVERT: 1967a123728 Rollup merge of #127586 - zachs18:more-must-use, r=cuviper REVERT: fc53324c54d Rollup merge of #126704 - sayantn:sha, r=Amanieu REVERT: 7850a64f5bb Forbid unsafe_op_in_unsafe_fn in vxworks specific os and sys files REVERT: 74dd96fbea9 chore: refactor backtrace style in panic REVERT: 0e4358de84e Auto merge of #128528 - workingjubilee:you-dont-need-to-see-this-cpuid-move-along, r=Amanieu REVERT: 9fa74abcf83 Move the standard library to a separate workspace REVERT: e13d132801a Auto merge of #128254 - Amanieu:orig-binary-search, r=tgross35 REVERT: 05d8d7c0765 Implement `UncheckedIterator` directly for `RepeatN` REVERT: a5fa13e131b Rollup merge of #128491 - c410-f3r:unlock-rfc-2011, r=workingjubilee REVERT: 28e4d22aec0 Rollup merge of #128453 - RalfJung:raw_eq, r=saethlin REVERT: db770c6262d std: Remove has_cpuid REVERT: 39aad04eaaf time.rs: remove "Basic usage text" REVERT: 7df583ccfb3 Dogfood REVERT: cb110515265 Add the `sha512`, `sm3` and `sm4` target features REVERT: 86ea79fb335 Fix mutability in doc tests for `BTreeSet` cursors REVERT: e844efffe8f Add a disclaimer about x86 `f128` math functions REVERT: 21d297b29ad Update comments for `{f16, f32, f64, f128}::midpoint` REVERT: ad27d08e73e Add `core` functions for `f16` and `f128` that require math routines REVERT: c6407b0bfa7 Add math functions for `f16` and `f128` REVERT: d9b1de5180d Add math intrinsics for `f16` and `f128` REVERT: c7be27f744a Introduce `Cursor`/`CursorMut`/`CursorMutKey` thrichotomy for `BTreeSet` like map API REVERT: 8835b0ffaef Fix some uses of "map" instead of "set" in `BTreeSet` cursor API docs REVERT: 07f64a8e22c Share `UnorderedKeyError` with `BTReeMap` for set API REVERT: f859e542648 Rollup merge of #128499 - Konippi:refactor-backtrace-formatting, r=tgross35 REVERT: fb966d2b046 Rollup merge of #128497 - Bryanskiy:fix-dropck-doc, r=lcnr REVERT: ab00ae63d7a Rollup merge of #128433 - hermit-os:hermit-unsafe_op_in_unsafe_fn, r=joboet REVERT: 3c1586b3ce8 Hide internal sort module REVERT: 2614bd2ae16 chore: refactor backtrace formatting REVERT: a8a46595ff6 fix dropck documentation for `[T;0]` special-case REVERT: b927541dc3f core: use `compare_bytes` for more slice element types REVERT: 589c0a0e872 fix(os/hermit): `deny(unsafe_op_in_unsafe_fn)` REVERT: 0260e47b16e fix(pal/hermit): `deny(unsafe_op_in_unsafe_fn)` REVERT: 7bd6b11e0ad refactor(pal/hermit): make `ENV` a non-mutable static REVERT: 32894e2b70e Rollup merge of #128416 - maurer:remove-android-hack, r=tgross35 REVERT: beb76c31275 Auto merge of #128461 - matthiaskrgr:rollup-3dpp11g, r=matthiaskrgr REVERT: 1e3976be11a Rollup merge of #128162 - ChrisDenton:cleanup, r=joboet REVERT: cde45b0a077 Rollup merge of #127567 - joboet:once_wait, r=Amanieu REVERT: 06076429681 Fix docs for OnceLock::get_mut_or_init REVERT: da484175cbd raw_eq: using it on bytes with provenance is not UB (outside const-eval) REVERT: cc6f37ff93f std: fix busy-waiting in `Once::wait_force`, add more tests REVERT: 6fd82f18f54 std: implement the `once_wait` feature REVERT: 0c56873d90f Remove unneeded `pub(crate)` REVERT: 787a1f7a2e6 Rollup merge of #128388 - beetrees:f16-f128-slightly-improve-windows-abi, r=tgross35 REVERT: e3a4ed3406a Rollup merge of #128387 - liigo:patch-14, r=tgross35 REVERT: 8b7f4ee6e3d refactor(pal/hermit): use default impl of `GlobalAlloc::alloc_zeroed` REVERT: c3370198cca refactor(pal/hermit): return `!` to satisfy rust-analyzer REVERT: 21887129721 Apply review comments REVERT: 2ebe00aa0ba PinCoerceUnsized trait into core REVERT: 7aafdcf2fa2 android: Remove libstd hacks for unsupported Android APIs REVERT: ba65c6c88c8 Move Windows implementation of anon pipe REVERT: 176508ce960 Match LLVM ABI in `extern "C"` functions for `f128` on Windows REVERT: 85e4ba09e56 Cleanup sys module to match house style REVERT: ddff2b608a9 Auto merge of #128083 - Mark-Simulacrum:bump-bootstrap, r=albertlarsan68 REVERT: e4b0e6d427b Rewrite binary search implementation REVERT: 556dc6028e1 More detailed note to deprecate ONCE_INIT REVERT: 440ec835e8f Auto merge of #128378 - matthiaskrgr:rollup-i3qz9uo, r=matthiaskrgr REVERT: a50fe577e5d Auto merge of #128250 - Amanieu:select_unpredictable, r=nikic REVERT: 47f9d6175ee Rollup merge of #128315 - zetanumbers:psvita-unsafe-in-unsafe, r=workingjubilee REVERT: f70ce7f3e03 Auto merge of #128234 - jcsp:retain-empty-case, r=tgross35 REVERT: 93b2f7c4e88 Insert some blank lines. REVERT: db0222e3e80 Move a comment. REVERT: 569ab6a3a03 CloneToUninit: use a private specialization trait REVERT: 26874cc98cc Sparkle some attributes over `CloneToUninit` stuff REVERT: e8c37187b60 impl CloneToUninit for Path and OsStr REVERT: ef8c591ec02 impl CloneToUninit for str and CStr REVERT: cc96f3e2d19 Stabilize offset_of_nested REVERT: 618fdd536b5 Auto merge of #128334 - matthiaskrgr:rollup-nhxdt0c, r=matthiaskrgr REVERT: e088cb1bcd7 Rollup merge of #128333 - RalfJung:miri-sync, r=RalfJung REVERT: 1ea0493512b Rollup merge of #128307 - ojeda:unescaped_backticks, r=GuillaumeGomez REVERT: 5d510999d8a Optimize empty case in Vec::retain REVERT: f2bcbecd66e Auto merge of #125016 - nicholasbishop:bishop-cb-112, r=tgross35 REVERT: 7a43febb9b1 Rollup merge of #128310 - kmicklas:btree-map-peek-next-docs, r=tgross35 REVERT: 03e5078d0f6 Rollup merge of #128055 - workingjubilee:deny-unsafe-ops-in-sys-personality-dwarf-eh, r=Amanieu REVERT: f9befad9f51 Rollup merge of #109174 - soerenmeier:cursor_fns, r=dtolnay REVERT: ed7d02fcc9b Update compiler_builtins to 0.1.114 REVERT: 80254cd2f12 Warn on `rustdoc::unescaped_backticks` for `core/alloc/std/test/proc_macro` REVERT: c8db8ead903 Remove spurious backticks detected by `rustdoc::unescaped_backticks` REVERT: d1d4fb32943 Reformat `use` declarations. REVERT: 3ec244feaeb Replace `io::Cursor::{remaining_slice, is_empty}` with `io::Cursor::{split, split_mut}` REVERT: 8744732f3ed Partially stabilize `io_error_more` REVERT: abc611ff511 step cfg(bootstrap) REVERT: 78cd7797193 Update CURRENT_RUSTC_VERSION REVERT: 70927dcd034 Add forbid(unsafe_op_in_unsafe_fn) REVERT: 06a22c946e3 Rollup merge of #128240 - mbrubeck:patch-3, r=joboet REVERT: 604d6183e4d Rollup merge of #128228 - slanterns:const_waker, r=dtolnay,oli-obk REVERT: 2a70839bf8f Rollup merge of #128103 - folkertdev:unsigned-int-is-multiple-of, r=Amanieu REVERT: 058f1d3e3a7 Rollup merge of #127765 - bitfield:fix_stdlib_doc_nits, r=dtolnay REVERT: 9a6c84e26c1 fix: psvita's std code REVERT: 5119266b79c Force LLVM to use CMOV for binary search REVERT: d6b6e639162 stabilize const_waker REVERT: 8e4f58a6520 Add missing periods on `BTreeMap` cursor `peek_next` docs REVERT: 458b9b07517 Implement cursors for `BTreeSet` REVERT: 65c6173bfe1 Update NonNull::align_offset quarantees REVERT: 02bf0de46e4 Enable `std::io::copy` specialisation for `std::pipe::{PipeReader, PipeWriter}` REVERT: 1f83bf3100e Rollup merge of #128282 - pitaj:nonzero_bitwise, r=workingjubilee REVERT: 357ff7a0265 Rollup merge of #128279 - slanterns:is_sorted, r=dtolnay REVERT: fcbdcae5542 stabilize `is_sorted` REVERT: c47f8bdd4f5 bitwise and bytewise methods on `NonZero` REVERT: 4ea98d76cfd Rollup merge of #128259 - sunshowers:msg-nosignal, r=Mark-Simulacrum REVERT: d6f970a682d Rollup merge of #125897 - RalfJung:from-ref, r=Amanieu REVERT: b014b0d7b74 Improve panic sections for sort*, sort_unstable* and select_nth_unstable* REVERT: 9bcfe84e72b Improve panic message and surrounding documentation for Ord violations REVERT: 339f7567cf0 Auto merge of #128255 - stepancheg:doc-shl, r=scottmcm REVERT: 7e55abb1837 Okay, I guess I have to give these a different feature name REVERT: bdc18e2ea2b impl Default for collection iterators that don't already have it REVERT: 0d6a7dd333b Merge from rustc REVERT: a66bc798ecd Auto merge of #127946 - tgross35:fmt-builders-set-result, r=cuviper REVERT: 2986bfed613 [illumos/solaris] set MSG_NOSIGNAL while writing to sockets REVERT: 3e854937500 Document int.checked_shl(BITS - 1) REVERT: 59f3fefb4cb Rollup merge of #128235 - harryscholes:fix-iterator-filter-docs, r=tgross35 REVERT: a2dbfd338e9 Rollup merge of #124941 - Skgland:stabilize-const-int-from-str, r=dtolnay REVERT: 5b78bae1394 Add links from `assert_eq!` docs to `debug_assert_eq!`, etc. REVERT: a0f135d76af Always set `result` during `finish()` in debug builders REVERT: bd11b3dcc6d Fix docs REVERT: 22ce603b463 Auto merge of #128165 - saethlin:optimize-clone-shims, r=compiler-errors REVERT: fb7d2a81c80 Fix doc nits REVERT: a1528206ab5 Rollup merge of #128170 - saethlin:clone-fn, r=compiler-errors REVERT: 0d636140614 Merge from rustc REVERT: cb8f69be7aa Rollup merge of #128211 - juliusl:pr/align-change-time, r=tgross35 REVERT: ba0582bf6c4 Rollup merge of #128150 - BoxyUwU:std_only_sized_const_params, r=workingjubilee REVERT: 30cfde4b97a Rollup merge of #127950 - nnethercote:rustfmt-skip-on-use-decls, r=cuviper REVERT: 8488ae6d29f Make Clone::clone a lang item REVERT: 1342ef157c3 fix: compilation issue w/ refactored type REVERT: 92c0ad77d5d Let InstCombine remove Clone shims inside Clone shims REVERT: c788415b025 Stop using `unsized_const_parameters` in core/std REVERT: ef4d4a039fe Auto merge of #128195 - matthiaskrgr:rollup-195dfdf, r=matthiaskrgr REVERT: 5b6c1e1ad32 Rollup merge of #128137 - GrigorenkoPV:cstr-derive, r=dtolnay REVERT: aaeac06292c Rollup merge of #127999 - ChrisDenton:arm32, r=Amanieu REVERT: f26f981c731 clarify interactions with MaybeUninit and UnsafeCell REVERT: 394c8640df0 remove duplicate explanations of the ptr to ref conversion rules REVERT: 571348bc357 create a new section on pointer to reference conversion REVERT: ea3a99f0fc7 Rollup merge of #128158 - workingjubilee:unsafe-wrap-personality-gcc, r=ChrisDenton REVERT: 886fe5b7f53 Rollup merge of #127300 - biabbas:fix_connect_timeout, r=tgross35 REVERT: b889a1defa7 CStr: derive PartialEq, Eq; add test for Ord REVERT: 3a181105a62 In connect timeout, read readiness of socket for vxworks. Check pollhup or pollerr for refused connections in linux REVERT: c4ee91f1305 Merge from rustc REVERT: 797c2498600 Implement `mixed_integer_ops_unsigned_sub` REVERT: 244d8430769 std: update comments on gcc personality fn REVERT: d252b6b475b std: unsafe-wrap gcc::rust_eh_personality and impl REVERT: 09bda4f2acb Rollup merge of #128135 - joboet:reduplicate_tls, r=tgross35 REVERT: a4c88bc2fbb Rollup merge of #128046 - GrigorenkoPV:90435, r=tgross35 REVERT: 2614d86fcb4 Rollup merge of #126548 - rik86189:issue-88264-fix, r=tgross35 REVERT: 75a178fdfa7 Rollup merge of #126042 - davidzeng0:master, r=Amanieu REVERT: 1e118aec933 Rollup merge of #128131 - ChrisDenton:stuff, r=workingjubilee REVERT: cea2ca9af78 Rollup merge of #128120 - compiler-errors:async-fn-name, r=oli-obk REVERT: 92e3688370a Rollup merge of #127733 - GrigorenkoPV:don't-forget, r=Amanieu REVERT: 9b1cffdc1be Rollup merge of #127480 - biabbas:vxworks, r=workingjubilee REVERT: 2632261f008 Rollup merge of #127252 - fitzgen:edge-cases-for-bitwise-operations, r=m-ou-se REVERT: b0d74144ae4 Rollup merge of #126152 - RalfJung:size_of_val_raw, r=saethlin REVERT: 6d0b7146359 Improved clarity of documentation for std::fs::create_dir_all REVERT: eb79e096922 std: use duplicate thread local state in tests REVERT: 8456a976820 Forbid unsafe_op_in_unsafe_fn in sys/pal/windows REVERT: 5a9fb1fc194 Import `core::ffi::c_void` in more places REVERT: 16450f7b3e9 Merge from rustc REVERT: 697c717b542 Add chroot unsupported implementation for VxWorks REVERT: 6242470207d Rollup merge of #128106 - hallfox:patch-1, r=ChrisDenton REVERT: de086ea59d4 Rollup merge of #128092 - ChrisDenton:wrappers, r=workingjubilee REVERT: ccba33ca2dc Rollup merge of #128043 - safinaskar:primitive, r=workingjubilee REVERT: a069998a10d Rollup merge of #127481 - a1phyr:pattern_gat, r=Amanieu REVERT: bc7345c7866 Rollup merge of #126770 - wr7:master, r=Amanieu REVERT: 21f6b6516e2 Rollup merge of #125962 - Coekjan:const-binary-heap, r=Amanieu REVERT: eee5bbaed57 Auto merge of #127153 - NobodyXu:pipe, r=ChrisDenton REVERT: fd3a45fc3f9 Gate AsyncFn* under async_closure feature REVERT: 0374ea22cab Add elem_offset and related methods REVERT: 2b3eacb22c6 library/core/src/primitive.rs: small doc fix REVERT: 45f80e6b25b Fix return type of FileAttr methods on AIX target REVERT: 6cabb65c3fa add `is_multiple_of` for unsigned integer types REVERT: 4c4a93a480e Initial implementation of anonymous_pipe REVERT: 63d29970101 Update process vxworks, set default stack size of 256 Kib for vxworks. User can set the stack size using RUST_MIN_STACK, with min size of libc::PTHREAD_STACK_MIN(4kib) REVERT: ee8604174b0 Rollup merge of #128089 - workingjubilee:commonly-wrapped-to-make-safe, r=ChrisDenton REVERT: ad9a52dcb35 Rollup merge of #125834 - workingjubilee:weaken-thir-unsafeck-for-addr-of-static-mut, r=compiler-errors REVERT: 642c69bbe40 Remove wrapper functions from c.rs REVERT: de2a0378391 std: Unsafe-wrap backtrace code held in-common REVERT: 155aef9d64b std: Unsafe-wrap alloc code held in-common REVERT: bee0155d119 Cfg disable on_broken_pipe_flag_used() for vxworks REVERT: 227b5afa55e Disable dirfd for vxworks, Return unsupported error from set_times and lchown for vxworks REVERT: 22a6797af81 Allow unused unsafe for vxworks in read_at and write at REVERT: 8be45a9e6a7 Docs for core::primitive: mention that "core" can be shadowed, too, so we should write "::core" REVERT: c039ee8ff7e library: vary unsafety in bootstrapping for SEH REVERT: 6765b971f38 std: unsafe-wrap personality::dwarf::eh REVERT: 971aa37f27b LocalWaker docs: Make long-ago omitted but probably intended changes REVERT: c4fdac9fe60 Docs for Waker and LocalWaker: Add cross-refs in comment REVERT: 7ae76f0ee2d Rollup merge of #128008 - weiznich:fix/121521, r=lcnr REVERT: 323e962d2cd Rollup merge of #127996 - ian-h-chamberlain:fix/horizon-warnings-unsafe-in-unsafe, r=tgross35 REVERT: ae6187f170c Rollup merge of #127415 - AljoschaMeyer:master, r=dtolnay REVERT: d6a36f520f5 Use given allocator instad of Global REVERT: d0bc9a0ec5d Start using `#[diagnostic::do_not_recommend]` in the standard library REVERT: ba43261b233 Rollup merge of #127583 - Nilstrieb:invalid-utf8, r=joboet REVERT: 0727e53d393 Fix warnings when checking armv6k-nintendo-3ds REVERT: bbe4da839fa Fix some `#[cfg_attr(not(doc), repr(..))]` REVERT: 9c299bc6b10 Implement `debug_more_non_exhaustive` REVERT: b405024dc09 Make use of raw strings in `core::fmt::builders` REVERT: 321dbf82a78 Deal with invalid UTF-8 from `gai_strerror` REVERT: 6aa00e1eece std::thread: available_parallelism implementation for vxWorks proposal. REVERT: 2fff48df757 Auto merge of #127722 - BoxyUwU:new_adt_const_params_limitations, r=compiler-errors REVERT: d7770e9cca2 Rollup merge of #128005 - ChrisDenton:msvc-include, r=joboet REVERT: 8fdee233d27 Rollup merge of #127734 - ChrisDenton:netc, r=Mark-Simulacrum REVERT: 3b2536ec206 Remove _tls_used hack REVERT: 07dbb381321 Rollup merge of #127873 - workingjubilee:forbid-unsafe-ops-for-kmc-solid, r=Amanieu REVERT: bd262955725 Rollup merge of #127843 - workingjubilee:break-up-big-ass-stack-overflow-fn, r=joboet REVERT: 00b4f61ec49 Inject win arm32 shims into metadata generation REVERT: 2b628674392 Rollup merge of #127918 - ChrisDenton:thread-name-string, r=joboet REVERT: a077eb1965c Rollup merge of #123196 - Ayush1325:uefi-process, r=joboet REVERT: eb09be43d35 std: forbid unwrapped unsafe in unsupported_backslash REVERT: dcb98546d31 kmc-solid: forbid(unsafe_op_in_unsafe_fn) REVERT: 845a2f78382 Auto merge of #127982 - matthiaskrgr:rollup-nzyvphj, r=matthiaskrgr REVERT: 00d6fc4cfef Rollup merge of #127978 - nyurik:lib-refs, r=workingjubilee REVERT: 4d8afcdd44b Avoid ref when using format! for perf REVERT: 9f20a0f28ba Rollup merge of #126199 - ivan-shrimp:nonzero_isqrt, r=tgross35 REVERT: f06530cc0c3 Rollup merge of #112328 - juliusl:pr/windows-add-change-time, r=ChrisDenton REVERT: 8d5cf50b19d uefi: process: Fixes from PR REVERT: c6cb67c41a3 uefi: process: Final Touchups REVERT: afe1ef08b0e uefi: process: Add CommandArgs support REVERT: ef6b1730a13 uefi: process: Add support for args REVERT: 1991fe38c57 uefi: process Implement inherit REVERT: 24a95828625 uefi: process: Add null protocol REVERT: 36a0e1e01c8 uefi: process: Add stderr support REVERT: b712e740ca4 uefi: process: Add support to capture stdout REVERT: e6eeb4ee295 uefi: Add process REVERT: f3b1c8a63e4 improve safety comment REVERT: 93489988c77 add `NonZero::isqrt` REVERT: edc4cdc351b Use `#[rustfmt::skip]` on some `use` groups to prevent reordering. REVERT: 489f1ef8747 unix: acquire-load NEED_ALTSTACK REVERT: 9e11e01d38f unix: Unsafe-wrap stack_overflow::{drop,make}_handler REVERT: 72c7444faf0 unix: Unsafe-wrap stack_overflow::cleanup REVERT: 33a32f20bfd unix: lift init of sigaltstack before sigaction REVERT: 9fb6e4958f7 unix: Unsafe-wrap stack_overflow::signal_handler REVERT: c99ebd411b7 Rollup merge of #127594 - c6c7:fuchsia-status-code-match-arm, r=tmandry REVERT: 83782615519 Move ThreadName conversions to &cstr/&str REVERT: 68e23910a05 Style change REVERT: 16bce8a458a Make `Thread::new_inner` a safe function REVERT: d1d98933f8f Rollup merge of #127748 - scottmcm:option_len, r=joboet REVERT: b0c85badd9f Rollup merge of #124881 - Sp00ph:reentrant_lock_tid, r=joboet REVERT: 7e218501a06 Update `ReentrantLock` implementation, add `CURRENT_ID` thread local. REVERT: c10a929ac5e Safely enforce thread name requirements REVERT: cc4ed954619 Rollup merge of #127077 - tbu-:pr_doc_fd_to_owned, r=workingjubilee REVERT: 37d7bff7bb1 Rollup merge of #127861 - Kriskras99:patch-1, r=tgross35 REVERT: 3d50720567e Rollup merge of #127859 - RalfJung:ptr-dyn-metadata, r=scottmcm REVERT: 1f3311b800b Rollup merge of #127845 - workingjubilee:actually-break-up-big-ass-stack-overflow-fn, r=joboet REVERT: 557859328cb Auto merge of #127865 - matthiaskrgr:rollup-8m49dlg, r=matthiaskrgr REVERT: 54728b12a9f feat: adding ext that returns change_time for Windows REVERT: b164bab985b Auto merge of #125942 - timokroeger:windows-once-futex, r=ChrisDenton REVERT: 0eda3a36123 Rollup merge of #127337 - celinval:intrinsics-fallback, r=oli-obk REVERT: ed3c6d115e4 Mention how you can go from `BorrowedFd` to `OwnedFd` and back REVERT: 455bd5705fb Make language around `ToOwned` for `BorrowedFd` more precise REVERT: ab7a0d4d6a5 Document the column numbers for the dbg! macro REVERT: 89cd225caaa ptr::metadata: update comment on vtable_ptr work-around REVERT: 51e54a4f5de ptr::metadata: avoid references to extern types REVERT: be0c06bc63e Split part of `adt_const_params` into `unsized_const_params` REVERT: 857ed93c04e Forbid `!Sized` types and references REVERT: a2cf63619d7 Rollup merge of #127813 - ChrisDenton:win-futex, r=joboet REVERT: aeae3328f01 Rollup merge of #127763 - ChrisDenton:safe-unsafe-unsafe, r=tgross35 REVERT: aedc16cadfe unix: unsafe-wrap install_main_guard_default REVERT: 4db3aa1e628 unix: clean up install_main_guard_freebsd REVERT: d167f00072d unix: stack_start_aligned is a safe fn REVERT: 27b79e6e1f7 unix: split stack_overflow::install_main_guard by os REVERT: e0ea7017a67 Prevent double reference in generic futex REVERT: 417b61f271f Narrow the scope of the ReadFile unsafe block REVERT: b4d1392064c forbid(unsafe_op_in_unsafe_fn) in sys/os_str REVERT: f431b519c02 Rollup merge of #127836 - workingjubilee:forbid-unsafe-ops-in-xous-uefi, r=tgross35 REVERT: 0a024bda728 Rollup merge of #127833 - risc0:erik/zkvm-deny-unsafe, r=workingjubilee REVERT: 0299bb5f196 Rollup merge of #127807 - ChrisDenton:win-parking, r=joboet REVERT: 61af010c325 Rollup merge of #127792 - workingjubilee:read-unaligned-is-dwarfier, r=joboet REVERT: d3cf2e16181 Rollup merge of #127444 - Sky9x:cstr-bytes-iter, r=dtolnay REVERT: 12075d15f76 Rollup merge of #126776 - nnethercote:rustfmt-use-pre-cleanups-2, r=cuviper REVERT: 00d603fc9c1 Rollup merge of #126271 - diondokter:dec2flt-skip-fast-path, r=tgross35 REVERT: 8490c84ffb2 Rollup merge of #125206 - mgeisler:simplify-std-env-vars, r=jhpratt,tgross35 REVERT: a752e3b2772 uefi: Forbid unwrapped unsafe in platform modules REVERT: 32a1b078ba4 Cfg nit REVERT: e189d3b30e1 xous: Forbid unwrapped unsafe in platform modules REVERT: 7ddd7f86509 zkvm: add `#[forbid(unsafe_op_in_unsafe_fn)]` in `stdlib` REVERT: 0723962ffe1 Adjust some comments on individual `use` declarations. REVERT: 4320ba0a9b5 Avoid comments that describe multiple `use` items. REVERT: 1aeddb00b1e Merge some `core::iter` entries. REVERT: 7a0b2fb5e16 Add unsafe blocks in unsafe Thread::new REVERT: 8e76b152b93 Remove `slice_to_end` REVERT: e8527cdadb6 std: unwrapped unsafe is VERBOTEN! REVERT: 5e4edbadcb7 Rollup merge of #127789 - Sword-Destiny:master, r=petrochenkov REVERT: 1b631e5f140 Use futex.rs for Windows thread parking REVERT: d59f862b675 std: Use read_unaligned for reading DWARF REVERT: 686f75bb7a6 Rollup merge of #127047 - tspiteri:f128-aconsts-lsd, r=tgross35 REVERT: 8b1d874a6ec deny unsafe_op_in_unsafe_fn for teeos REVERT: f8bb325e1cf clean unsafe op in unsafe fn REVERT: b5970178b63 clean unsafe op in unsafe fn REVERT: 9fd9c61c0ef clean unsafe op in unsafe fn REVERT: e0c57e42237 delete #![allow(unsafe_op_in_unsafe_fn)] REVERT: 704f56f5d84 `impl Send + Sync` and override `count` for the `CStr::bytes` iterator REVERT: d50143fddb9 Update name of Windows abort constant to match platform documentation REVERT: cbaa8317349 Add match arm for Fuchsia status code upon an abort in a test REVERT: a778c83ad92 Auto merge of #127777 - matthiaskrgr:rollup-qp2vkan, r=matthiaskrgr REVERT: 65355912072 Rollup merge of #124921 - RalfJung:offset-from-same-addr, r=oli-obk REVERT: f15715f3e48 lib: replace some `mem::forget`'s with `ManuallyDrop` REVERT: ac443f29c05 Auto merge of #127020 - tgross35:f16-f128-classify, r=workingjubilee REVERT: 57937d7f2bd allow(unsafe_op_in_unsafe_fn) on some functions REVERT: 94b381d6fc6 Some Windows functions are safe REVERT: f3bb34b1088 Deny more windows unsafe_op_in_unsafe_fn REVERT: 9bbf09d3d07 Windows: move BSD socket shims to netc REVERT: d76c965affa Remove generic lifetime parameter of trait `Pattern` REVERT: eae94518584 Rollup merge of #127750 - ChrisDenton:safe-unsafe-unsafe, r=workingjubilee REVERT: 6257980b38d Rollup merge of #127744 - workingjubilee:deny-unsafe-op-in-std, r=jhpratt REVERT: 05614f3ce16 Rollup merge of #127712 - ChrisDenton:raw-types, r=workingjubilee REVERT: 14c24b1ba4c Mark some `f16` and `f128` functions unstably const REVERT: ad3db57a529 Use Option's discriminant as its size hint REVERT: 1b70afd5267 Move safety comment outside unsafe block REVERT: 3c286d52b7d Make os/windows default to deny unsafe in unsafe REVERT: d96ed862d21 Make pal/windows default to deny unsafe in unsafe REVERT: bb3f60f0e69 Fix Windows 7 REVERT: 9fc6710fe07 Auto merge of #127719 - devnexen:math_log_fix_solill, r=Amanieu REVERT: decdb067d63 Don't re-export `c_int` from `c` REVERT: a1a1c6a2d51 Remove DWORD REVERT: 7d189919173 Remove ULONG REVERT: d89bce6a28b Remove PSRWLOCK REVERT: d3205de3d53 Remove LPVOID REVERT: 68ac381171e Remove LPSECURITY_ATTRIBUTES REVERT: 6d037b83d39 Remove LPOVERLAPPED REVERT: 61f617d370a Remove LPCVOID REVERT: 8a2537133ee Remove SIZE_T REVERT: cd51de1f064 Remove CHAR REVERT: 00a5b3b8733 Remove USHORT REVERT: d621d21f702 Remove LPWSTR REVERT: 0b22ecb55af Remove UINT REVERT: 18adceff5ae Remove LONG REVERT: 4eaaf7dcb61 Remove LARGE_INTEGER REVERT: aa45985349c Remove NonZeroDWORD REVERT: d7aa7cf7242 Auto merge of #127732 - GrigorenkoPV:teeos-safe-sys-init, r=Amanieu REVERT: 5ff7b404d5e std: Unsafe-wrap std::sync REVERT: e8fa3ef2c24 std: Unsafe-wrap in Wtf8 impl REVERT: 8c3a9c1c939 std: Unsafe-wrap std::io REVERT: 91b7331a825 std: Directly call unsafe {un,}setenv in env REVERT: 8c75111da55 std: Unsafe-wrap OSStr{,ing}::from_encoded_bytes_unchecked REVERT: 4679f9a6cff std: Unsafe-wrap HashMap::get_many_unchecked_mut REVERT: ac0fd279184 std: deny(unsafe_op_in_unsafe_fn) but allow sites REVERT: f710e38693e Add `classify` and related methods for `f16` and `f128` REVERT: 009660d51cc std: removes logarithms family function edge cases handling for solaris. REVERT: 3492a6b5146 Auto merge of #127728 - matthiaskrgr:rollup-ercdbjd, r=matthiaskrgr REVERT: 08732993c73 sys::init is not unsafe on teeos REVERT: 6c4029ad51b Rollup merge of #127592 - tesuji:patch-1, r=Mark-Simulacrum REVERT: 7cd8086b6c1 Auto merge of #125935 - madsmtm:merge-os-apple, r=workingjubilee REVERT: cfb0556a7f1 Merge Apple `std::os` extensions modules into `std::os::darwin` REVERT: 54435f79fa5 Rollup merge of #127704 - workingjubilee:fixup-better-than, r=ChrisDenton REVERT: e1229496e7f Auto merge of #127706 - workingjubilee:rollup-d07ij30, r=workingjubilee REVERT: 30331206bd2 Rollup merge of #127659 - saethlin:manually-drop-bufwriter, r=joboet REVERT: e9eb7de0b4a Rollup merge of #127446 - zachs18:miri-stdlib-leaks-core-alloc, r=Mark-Simulacrum REVERT: 3ad25605a1f Rollup merge of #127370 - ChrisDenton:win-sys, r=Mark-Simulacrum REVERT: 05bf6bcfaeb doc: Suggest `str::repeat` over `iter::repeat().take().collect()` REVERT: 96e8ba7a40c Fix minor typos in std::process doc on Win argv REVERT: 6b67c664112 Auto merge of #126958 - dtolnay:u32char, r=Mark-Simulacrum REVERT: 591aaaf1e3e std::unix::fs: removing, now useless, layers predating macOs 10.10. REVERT: 94ec6e79526 Auto merge of #127674 - jhpratt:rollup-0dxy3k7, r=jhpratt REVERT: a7c1f608ce4 Rollup merge of #127668 - spencer3035:improve-slice-doc, r=jhpratt REVERT: 1e49e055a69 Rollup merge of #127661 - eduardosm:stabilize-io_slice_advance, r=cuviper REVERT: c79e0030810 Auto merge of #127397 - jyn514:multi-thread-panic-hook, r=workingjubilee REVERT: 206678cfcd3 Auto merge of #126606 - zachs18:patch-2, r=joboet REVERT: 1bb035080b7 Updated slice documentation REVERT: c8b79ddd46c Use ManuallyDrop in BufWriter::into_parts REVERT: 20e64bd6cd3 Use is_val_statically_known to optimize pow REVERT: 6e26e27ee92 Stabilize io_slice_advance REVERT: cac66641bfb Rename the internal `const_strlen` to just `strlen` REVERT: 39647aba92c fix interleaved panic output REVERT: 0476fc4842e Rollup merge of #127433 - dtolnay:conststrlen, r=workingjubilee REVERT: f66bd5fdfbd Rollup merge of #126827 - the8472:pidfd-spawn, r=workingjubilee REVERT: 1e5cd219cb6 Rollup merge of #124980 - zachs18:rc-allocator, r=Amanieu REVERT: 949f0d63178 Add instability attribute on private const_strlen function REVERT: 20bfac6c159 Rollup merge of #127422 - greaka:master, r=workingjubilee REVERT: 79855bb9ba4 [library/std/src/process.rs] `PartialEq` & `Eq` for `ExitCode` REVERT: 05ee32298cb Explicitly unroll integer pow for small exponents REVERT: 4cfe24a3555 Optimize integer pow by removing exit branch REVERT: f937ef12bda Rollup merge of #127599 - tgross35:lazy_cell_consume-rename, r=workingjubilee REVERT: fde7fd261f2 Rollup merge of #127588 - uweigand:s390x-f16-doctests, r=tgross35 REVERT: ed47f986f1b Rollup merge of #127572 - tbu-:pr_debug_event_nonpacked, r=jhpratt REVERT: e5c8b859b88 Rollup merge of #124599 - estebank:issue-41708, r=wesleywiser REVERT: b71b538ec26 Rename `lazy_cell_consume` to `lazy_cell_into_inner` REVERT: 3b86ae3449f Explicitly ignore `into_raw_handle()` using `let _ =` in sys/pal/windows. REVERT: 9efc1cb294a core: Limit remaining f16 doctests to x86_64 linux REVERT: 1cb5354fc6c Add `must_use` to IntoRawFd/IntoRawSocket/IntoRawHandle's methods. REVERT: 697377abf32 Clarify/add `must_use` messages for more `into_raw*` functions of `alloc` types. REVERT: a7bec568626 size_of_val_raw: for length 0 this is safe to call REVERT: a18fbd0ad0e Rollup merge of #127554 - ferrocene:tshepang-add-missing-attribute, r=pietroalbini REVERT: e419147a511 Don't mark `DEBUG_EVENT` struct as `repr(packed)` REVERT: 4552576f397 Auto merge of #126690 - andyolivares:feature/show_window, r=dtolnay REVERT: 6f6e343956a Rollup merge of #127091 - Sky9x:fused-error-sources-iter, r=dtolnay REVERT: 0d64105175e Fixed doc links REVERT: 4fb7b225972 Few changes to doc comments. Added tracking issue number. REVERT: fe62f6f8ad6 Exposing STARTUPINFOW.wShowWindow in CommandExt (show_window function) to control how a new process should display its window (normal, minimized, maximized, etc) REVERT: 7d20047874d do not run test where it cannot run REVERT: c5f1c76ddea Auto merge of #127235 - martn3:no-mips-f16, r=tgross35,scottmcm REVERT: 3fefa04a3c1 Rollup merge of #127460 - Borgerr:clarify-drop-comment, r=jhpratt REVERT: 895175ada33 Rollup merge of #127355 - aceArt-GmbH:126475, r=oli-obk REVERT: 57cea32952c Rollup merge of #120248 - WaffleLapkin:bonk-ptr-object-casts, r=compiler-errors,oli-obk,lnicola REVERT: e74955e1f84 Attempt to fix CI REVERT: 39c4daabd50 Reset sigpipe not supported for vxworks REVERT: e466bf57650 Rollup merge of #127367 - ChrisDenton:run-sync, r=Nilstrieb REVERT: 90504f870c5 Rollup merge of #126921 - workingjubilee:outline-va-list, r=Nilstrieb REVERT: c6b3f3db220 Auto merge of #127454 - matthiaskrgr:rollup-k3vfen2, r=matthiaskrgr REVERT: 29d792329d4 Move/change declaration of `mod exit_guard;` REVERT: ecc90251720 clarify `sys::unix::fd::FileDesc::drop` comment (#66876) REVERT: 35c5a456fea Rollup merge of #127447 - RalfJung:once_lock_miri, r=joboet REVERT: 9f7100d382c Rollup merge of #127354 - nicholasbishop:bishop-sized-doc, r=Nilstrieb REVERT: ee06e7daee6 Rollup merge of #127297 - the8472:path-new-hash, r=Nilstrieb REVERT: 2206c6b52b9 Rollup merge of #127189 - GrigorenkoPV:linkedlist-cursor-list, r=Nilstrieb REVERT: 41bcc362ad5 Rollup merge of #127179 - tgross35:typeid-debug-hex, r=Nilstrieb REVERT: 7177ac878cc once_lock: make test not take as long in Miri REVERT: 294d87f0c25 Remove non-focused memory leak in `std` doctest for Miri. REVERT: a86fd0f0d19 Specialize `TrustedLen` for `Iterator::unzip()` REVERT: 5515bbad984 Mitigate focused memory leaks in `core` doctests for Miri. REVERT: 3a0fe26db17 Remove non-focused memory leaks in `core` doctests for Miri. REVERT: 20d6cb372e6 Mitigate focused memory leaks in `alloc` doctests for Miri. REVERT: cac890232ed Remove non-focused memory leaks in `alloc` doctests for Miri. REVERT: bcdc8e8471d Stabilize const_cstr_from_ptr (CStr::from_ptr, CStr::count_bytes) REVERT: ca537d2cb33 Fix them doc examples some more REVERT: be23cef3a42 Fix doc examples REVERT: a48f566b9a4 offset_from intrinsic: always allow pointers to point to the same address REVERT: 8d0199656c4 Run formatter on alloc/src/boxed.rs REVERT: 9919a83b414 Mark format! with must_use hint REVERT: 0907955d257 as_simd: fix comment to be in line with 507583a (#121201) REVERT: 5569eceddd0 Rollup merge of #127275 - RalfJung:offset-from-isize-min, r=Amanieu REVERT: c3b602af8ce Add missing try_new_uninit_slice_in and try_new_zeroed_slice_in REVERT: 2337ab518af Rollup merge of #125751 - pitaj:new_range_api, r=jhpratt REVERT: ad4fde64af5 Rollup merge of #127363 - GuillaumeGomez:improve-fmt-code-readability, r=Amanieu REVERT: 3eeca5f7708 Rollup merge of #127107 - mu001999-contrib:dead/enhance-2, r=pnkfelix REVERT: 1b5e5ac49eb Rollup merge of #123600 - tisonkun:path_with_extension, r=dtolnay REVERT: 5e9d4458222 Attempt to fix CI REVERT: d8965d365be add `new_range_api` for RFC 3550 REVERT: ca0f659f69d Move exit guard from sys::common::exit_guard to sys::exit_guard. REVERT: cf300a7e34b Update library/std/src/sys/pal/common/exit_guard.rs REVERT: ba4c71a7433 add unit tests for extra extension feature REVERT: 55fc20b7cbd update comments REVERT: 6b7a259b4f0 Add experimental raw-dylib feature to std REVERT: c452e620459 Use windows_targets macro for alloc REVERT: 521c81ab1c4 Run alloc sync tests REVERT: 2fcdebb68d7 Improve readability of some fmt code examples REVERT: 625bcc4987d Rollup merge of #127320 - ChrisDenton:win-sys, r=Mark-Simulacrum REVERT: f8caf5f24be Rollup merge of #127214 - bjorn3:miri_native_unwind, r=oli-obk REVERT: 1862054af88 Describe Sized requirements for mem::offset_of REVERT: e26c8818397 impl FusedIterator and a size hint for the error sources iter REVERT: 8f1c6640319 core: erase redundant stability attrs in va_list REVERT: 60c33a58766 library: outline VaList into ffi::va_list REVERT: 03d11c20585 Auto merge of #126171 - RalfJung:simd_bitmask_multibyte, r=workingjubilee REVERT: 54875740eef Document safety of a few intrinsics REVERT: 87fcd2f5c73 Move a few intrinsics to use Rust abi REVERT: 6b549baafd8 mark `can_not_overflow` as `#[rustc_const_stable(...)]` REVERT: 259c058b9f7 stabilize `const_int_from_str` REVERT: 297850a677e Add more checks for pointers with vtable meta REVERT: f58a3d6903e Improve dead code analysis REVERT: 515bd305955 Add comments to windows_targets.rs REVERT: 89d2de0f95f Update windows-bindgen to 0.58.0 REVERT: 0860a040c83 also remove redundant requirements from offset() REVERT: 6f80604442b offset_from: "the difference must fit in an isize" is a corollary REVERT: de4f5c2ca62 Rollup merge of #127303 - cuishuang:master, r=jhpratt REVERT: 56c73c378a5 Rollup merge of #127195 - biabbas:vxworks_cleanup, r=jhpratt REVERT: 5dfdef71fae Rollup merge of #126792 - wooden-worm:master, r=Mark-Simulacrum REVERT: 4df2059a6f7 chore: remove repeat words REVERT: acbefbbdec7 impl PathBuf::add_extension and Path::with_added_extension REVERT: 13d5a423f3d Auto merge of #127226 - mat-1:optimize-siphash-round, r=nnethercote REVERT: ed3d4878d34 stir the hash state a little to avoid prefix collisions REVERT: 5ca124f6d8a Add more test cases for path comparisons REVERT: 33bc557dd48 Add test case demonstrating equality of paths "foo/bar" and "foobar" REVERT: 079f99970d6 Move unique_thread_exit call to lang_start_internal so it is not in a generic function, and wrap it in `catch_unwind` REVERT: 47d0cbc7e2f Remove Miri special-case REVERT: 596be7ee7d7 Use pthread_t instead of numeric thread id REVERT: 2e90f6f5e7c Use libc::pause instead of std::thread::park in wait-for-exit loop REVERT: 1fd23e8568a core: Limit four f16 doctests to x86_64 linux REVERT: e6f15c579fa std: Set has_reliable_f16 to false for MIPS targets in build.rs REVERT: 67535b62417 library/std/build.rs: "powerpc64le" is not a target_arch REVERT: 5b0d82f32d8 Rollup merge of #127204 - dimpolo:stabilize_atomic_bool_fetch_not, r=jhpratt REVERT: b184a84f13c Rollup merge of #123588 - tgross35:stabilize-assert_unchecked, r=dtolnay REVERT: 2a81053036c Fall back on remove dir implementation for vxworks REVERT: 538fe8146ef Add edge-case examples to `{count,leading,trailing}_{ones,zeros}` methods REVERT: a8b6d0a2e51 Rollup merge of #127230 - hattizai:patch01, r=saethlin REVERT: 4d7cbb257ee chore: remove duplicate words REVERT: 645e9f24d68 Optimize SipHash by reordering compress instructions REVERT: c5ab1f01d8c Rollup merge of #127128 - elomatreb:elomatreb/stabilize-duration_abs_diff, r=joboet REVERT: f09067288ce Rollup merge of #126732 - StackOverflowExcept1on:master, r=m-ou-se REVERT: 1dc4f05eed8 Use the native unwind function in miri where possible REVERT: 4fff3351c87 Avoid MIR bloat in inlining REVERT: 4385efde634 Stabilize atomic_bool_fetch_not REVERT: 6c3359cdb0b Rollup merge of #127182 - danielhuang:patch-4, r=Nilstrieb REVERT: a0a438a75f2 Remove unqualified import io:: Error for vxworks as all Error references are qualified in process_vxworks.rs REVERT: 2a65e9fd644 Auto merge of #127026 - Urgau:cleanup-bootstrap-check-cfg, r=Kobzol REVERT: bba22002ec8 LinkedList's Cursor: method to get a ref to the cursor's list REVERT: 40a9be9a29e Update ip_addr.rs REVERT: 986dbd1b458 Print `TypeId` as hex for debugging REVERT: f27723e63ee Rollup merge of #127069 - Sky9x:fmt-pointer-use-addr, r=Nilstrieb REVERT: b068fce0ad9 Rollup merge of #126895 - betelgeuse:improve_simd_gather_documentation, r=Amanieu REVERT: a6b22e95975 Rollup merge of #127134 - tgross35:typeid-debug, r=Nilstrieb REVERT: 7f0bb45d5b9 Rollup merge of #126906 - GrigorenkoPV:fixme-split_at_first, r=Mark-Simulacrum REVERT: b0feb54c3d8 Rollup merge of #126705 - safinaskar:panic, r=Mark-Simulacrum REVERT: b8977f5a191 Auto merge of #127133 - matthiaskrgr:rollup-jxkp3yf, r=matthiaskrgr REVERT: affa2f90405 Print `TypeId` as a `u128` for `Debug` REVERT: 05a472c8d62 Rollup merge of #127122 - TDecking:div_ceil, r=Nilstrieb REVERT: 9b3a5111038 Auto merge of #120639 - fee1-dead-contrib:new-effects-desugaring, r=oli-obk REVERT: f96a3214d6b Stabilize `duration_abs_diff` REVERT: bf9096fc013 small correction to fmt::Pointer impl REVERT: 171f5dbb17b Auto merge of #127121 - GuillaumeGomez:rollup-xjjjckn, r=GuillaumeGomez REVERT: 50a66465304 Remove uneccessary condition in `div_ceil` REVERT: 79143898a34 Updated docs on `#[panic_handler]` in `library/core/src/lib.rs` REVERT: 1858bdce9b8 Rollup merge of #127073 - Sky9x:unnecessary-seqcst, r=Nilstrieb REVERT: aaed20934c7 Rollup merge of #127072 - Sky9x:docs-includes-vs-does-include, r=scottmcm REVERT: e5a577d85dc Auto merge of #127119 - RalfJung:miri-sync, r=RalfJung REVERT: 77a5b51293f Rollup merge of #126953 - joboet:lazy_key, r=jhpratt REVERT: 8641f6a3b19 Merge from rustc REVERT: 402992c7d21 Rollup merge of #127071 - Sky9x:remove-ptr-to-from-bits, r=scottmcm REVERT: 0a2d8e47740 Rollup merge of #127070 - Sky9x:unit-const-param-ty, r=BoxyUwU REVERT: 663f3d54372 Rollup merge of #127055 - shepmaster:hash-finish-must-use, r=dtolnay REVERT: 729a10a00b8 address review comments REVERT: db228b821dd general fixups and turn `TODO`s into `FIXME`s REVERT: 47492c9ec94 Implement `Min` trait in new solver REVERT: cc4a0293697 implement new effects desugaring REVERT: d6fadf5ac19 std: add safety comments REVERT: 8c3c7dcea79 Rollup merge of #126970 - DaniPopes:simplify-str-clone_into, r=cuviper REVERT: ae98528d9f3 Rollup merge of #126956 - joboet:fmt_no_extern_ty, r=RalfJung REVERT: 652f0b8fe38 Merge from rustc REVERT: 48dc678b2c6 Remove unnecessary SeqCst in `impl fmt::Pointer for AtomicPtr` REVERT: e6e5e84cae6 docs: say "includes" instead of "does include" REVERT: a722d391cd8 Remove (deprecated & unstable) {to,from}_bits pointer methods REVERT: 2ed9c9f5b62 add () to the marker_impls macro for ConstParamTy REVERT: fdfe0148965 Mark `Hasher::finish` as #[must_use] REVERT: 2bd2069f1dd fix least significant digits of f128 associated constants REVERT: 8db57c2b618 core: improve comment REVERT: 1f8c8f42e51 Cleanup bootstrap check-cfg REVERT: 6c38c60873f Rollup merge of #126980 - Borgerr:fix-extendfromslice-check, r=workingjubilee REVERT: a2dc9b539e3 Rollup merge of #126929 - nnethercote:rm-__rust_force_expr, r=oli-obk REVERT: cf231e8ada7 Merge from rustc REVERT: a8b311eb853 Auto merge of #126608 - tgross35:f16-f128-library, r=Mark-Simulacrum REVERT: 4788a93eee2 std: test a variety of ways to extend a Wtf8Buf REVERT: 57c2de81f2b set self.is_known_utf8 to false in extend_from_slice REVERT: c14a130aa4a Rollup merge of #126879 - the8472:next-chunk-filter-drop, r=cuviper REVERT: f6fdef3996a core: avoid `extern` types in formatting infrastructure REVERT: 43a865ad540 fix UI test, simplify error message REVERT: ff33a6672e7 regression test for leaks in the the Filter::next_chunk implementation REVERT: f90972a4104 add comments explaining optimizations for Filter::next_chunk REVERT: 4039a7f34e7 fix Drop items getting leaked in Filter::next_chunk REVERT: 0351c5316c0 Simplify `str::clone_into` REVERT: 5aedb8ada69 Rollup merge of #126946 - cyrgani:patch-1, r=compiler-errors REVERT: 5664da3fcac Rollup merge of #126927 - workingjubilee:vaargsafe-is-unsafe, r=joboet REVERT: 927337346fd Rollup merge of #126885 - Borgerr:rm_internal_pathbuf_asmutvec, r=workingjubilee REVERT: 46074aad759 Rollup merge of #126302 - mu001999-contrib:ignore/default, r=michaelwoerister REVERT: 0fe53622318 Stabilize const unchecked conversion from u32 to char REVERT: 9dcaa15a8dc std: separate TLS key creation from TLS access REVERT: 5d08a54141c Detect unused structs which derived Default REVERT: e6c45e4a711 `PathBuf::as_mut_vec` removed and verified for UEFI and Windows platforms #126333 REVERT: 7cec6ef8d5e remove references to `PathBuf::as_mut_vec` in `PathBuf::_set_extension` REVERT: 37f78f46760 inner truncate methods for UEFI platforms REVERT: cfb802176cb #126333 remove `PathBuf::as_mut_vec` reference at top of `PathBuf::_push` REVERT: 3edb521863d simd_bitmask intrinsic: add a non-power-of-2 multi-byte example REVERT: 2ddf7942352 Add missing slash in const_eval_select doc comment REVERT: 19cfdb2c317 Add tests for `f16` and `f128` REVERT: 561daffd3f5 Add more `f16` and `f128` library functions and constants REVERT: 6cb3d34841e Add doctests to existing `f16` and `f128` functions REVERT: b0e050324f9 Add build.rs config for reliable `f16` and `f128` REVERT: 028026b9b30 Remove `__rust_force_expr`. REVERT: 1069a689007 core: VaArgSafe is an unsafe trait REVERT: a451b2a9f8b Auto merge of #126852 - scottmcm:more-checked-math-tweaks, r=Amanieu REVERT: 17d03b950a4 Check that we get somewhat sane PIDs when spawning with pidfds REVERT: 4c9a96eebda more fine-grained feature-detection for pidfd spawning REVERT: bf06e436d4a document safety properties of the internal Process::new constructor REVERT: 9212236fc18 use pidfd_spawn for faster process creation when pidfds are requested REVERT: 4815f2968d4 document the cvt methods REVERT: 1bd207e6b0a Rollup merge of #126904 - GrigorenkoPV:nonzero-fixme, r=joboet REVERT: 2676918a59b Rollup merge of #125575 - dingxiangfei2009:derive-smart-ptr, r=davidtwco REVERT: 9dcffa5782f Rollup merge of #125082 - kpreid:const-uninit, r=dtolnay REVERT: cf34f71c117 Replace `MaybeUninit::uninit_array()` with array repeat expression. REVERT: e51d8a2224f Auto merge of #126523 - joboet:the_great_big_tls_refactor, r=Mark-Simulacrum REVERT: 2b8c7a3813f Small fixme in core now that split_first has no codegen issues REVERT: 532304befc3 Small fixme in core now that NonZero is generic REVERT: 5ae0378035a std: fix wasm builds REVERT: ae08c581475 Rollup merge of #126213 - zachs18:atomicbool-u8-i8-from-ptr-alignment, r=Nilstrieb REVERT: 071e80d6c4a Fix simd_gather documentation REVERT: 0c4a661ebdf wasm64 build with target-feature=+simd128,+atomics REVERT: 36a20f7b383 Reword docs for `f32` and `f64` REVERT: 6839ec5efd2 Extract repeated constants from `f32` and `f64` source REVERT: c26bd79991f Rollup merge of #126854 - devnexen:std_unix_os_fallback_upd, r=Mark-Simulacrum REVERT: 828e528d416 Rollup merge of #126807 - devnexen:copy_file_macos_simpl, r=Mark-Simulacrum REVERT: 5fc66ddb6d3 Implement `unsigned_signed_diff` REVERT: e4bc79db7fe Also get `add nuw` from `uN::checked_add` REVERT: 7c83a041921 SmartPointer derive-macro REVERT: f0b95fcce71 fix build REVERT: 12ec5b7b691 Rollup merge of #126783 - tguichaoua:fix_tcplistener_into_incoming_issue_number, r=workingjubilee REVERT: eb265d0841e std::unix::os::home_dir: fallback's optimisation. REVERT: a48f3d6475d Auto merge of #126838 - matthiaskrgr:rollup-qkop22o, r=matthiaskrgr REVERT: ec8af4b3c06 Rollup merge of #126552 - fee1-dead-contrib:rmfx, r=compiler-errors REVERT: 6d6ba925574 Rollup merge of #126140 - eduardosm:stabilize-fs_try_exists, r=Amanieu REVERT: e1edea8f3a4 Auto merge of #116113 - kpreid:arcmut, r=dtolnay REVERT: 49d4fdb09f1 Generalize `{Rc,Arc}::make_mut()` to unsized types. REVERT: 5ac719ed6a2 Replace `WriteCloneIntoRaw` with `CloneToUninit`. REVERT: a4ca461939e Add `core::clone::CloneToUninit`. REVERT: 78368435c65 Auto merge of #126750 - scottmcm:less-unlikely, r=jhpratt REVERT: 934e7286794 Auto merge of #124101 - the8472:pidfd-methods, r=cuviper REVERT: c2ec99b6637 to extract a pidfd we must consume the child REVERT: f7cf777c00b Add PidFd::{kill, wait, try_wait} REVERT: d688595fa6c std::unix::fs: copy simplification for apple. REVERT: bb602cf940d Auto merge of #125853 - tesuji:promote-fail-fast, r=cjgillot REVERT: 1f1793634b4 update intrinsic const param counting REVERT: 5e7ce0bad23 Remove `feature(effects)` from the standard library REVERT: 8902c171c30 Auto merge of #126781 - matthiaskrgr:rollup-5u4pens, r=matthiaskrgr REVERT: 54eaed7e5ef fix issue number REVERT: 2e01ae34277 Rollup merge of #126613 - tgross35:log-test-update, r=cuviper REVERT: 306d7bf153a Stop using `unlikely` in `strict_*` methods REVERT: a8ab1ceb396 [GVN] Add tests for generic pointees with PtrMetadata REVERT: a272844a6e1 Don't perform mitigation for thread-unsafe libc::exit under Miri. REVERT: 5035a17dec1 fix rustdoc URL REVERT: 1530977b9a5 On `target_os = "linux"`, ensure that only one Rust thread calls `libc::exit` or returns from `main`. REVERT: 7e940ba00cf Auto merge of #126578 - scottmcm:inlining-bonuses-too, r=davidtwco REVERT: 9a945fdf0e9 Auto merge of #124032 - Voultapher:a-new-sort, r=thomcc REVERT: dbaf524df30 Rollup merge of #126737 - fee1-dead-contrib:rm-const-closures, r=compiler-errors REVERT: 0f6922d6272 Fix wrong big O star bracing in the doc comments REVERT: 7bf7f578614 Remove `feature(const_closures)` from libcore REVERT: b4e2e4ac6e9 Auto merge of #126736 - matthiaskrgr:rollup-rb20oe3, r=matthiaskrgr REVERT: 0829ab8d1b7 Rollup merge of #126717 - nnethercote:rustfmt-use-pre-cleanups, r=jieyouxu REVERT: f1c9c809b1f Rollup merge of #126711 - GKFX:const-option-as-slice, r=oli-obk REVERT: e0572323ddb Auto merge of #116088 - nbdd0121:unwind, r=Amanieu,RalfJung REVERT: 13ea648b170 Stabilize `PanicInfo::message()` and `PanicMessage` REVERT: b6a38581515 Rollup merge of #126703 - the8472:on-blackbox-crypto-use, r=scottmcm REVERT: 847726d1be8 Shrink some slice iterator MIR REVERT: 1ba2fa4b637 Stabilize `hint_assert_unchecked` REVERT: 9d0041c40d7 Update documentation for `hint::assert_unchecked` REVERT: e3e84a75a9b Add blank lines after module-level `//` comments. REVERT: 36ad0db0a23 Add blank lines after module-level `//!` comments. REVERT: 4e67110a2fb Convert some module-level `//` and `///` comments to `//!`. REVERT: 669d6fce08c Make Option::as_[mut_]slice const REVERT: 4ae781cb5e2 reword the hint::blackbox non-guarantees REVERT: dd7c901e95d core: add tracking issue for `array::repeat` REVERT: 5ddeaca202b core: simplify implementation of `array::repeat`, address other nits REVERT: 62f7a4e4e92 core: implement `UncheckedIterator` for `RepeatN` REVERT: 387fd1f34c6 core: implement `array::repeat` REVERT: 3fc18d0b40c Add a hack to prevent proc_macro misopt in CI REVERT: a95938d6730 Stabilise c_unwind REVERT: 2a5e5b887ef Rollup merge of #125787 - Oneirical:infinite-test-a-novel, r=jieyouxu REVERT: 227994dbde2 try implementing suggestions REVERT: 78867ab1aa0 run_make_support nm implementation + bin-emit-no-symbols rmake rewrite REVERT: 76e61bf77a6 Replace `move||` with `move ||` in `compiler/` and `library/` REVERT: 13a31b63b4f Auto merge of #126330 - m-ou-se:panic-message-type, r=Amanieu REVERT: 42802a3a09e Print the tested value in int_log tests REVERT: ea1ab74eb6d Add missing CopyMarker impl REVERT: 384c2054629 Revert panic_safe test changes REVERT: ca458bac5ae Add PanicMessage type for PanicInfo::message(). REVERT: 22389455823 Add tracking issue to async_drop API REVERT: 0b3227b6dac std: rename module for clarity REVERT: 2b9a4f38bd6 std: update TLS module documentation REVERT: 00d4964bb22 std: use the `c_int` from `core::ffi` instead of `libc` REVERT: bd3b9eca35a std: simplify `#[cfg]`s for TLS REVERT: 78eaad5fb0a Fix unintended regression for Freeze + Copy types REVERT: 8cd20cb8dc1 Auto merge of #126569 - jieyouxu:rollup-1uvkb2y, r=jieyouxu REVERT: c1acd7a6844 Rollup merge of #126531 - slanterns:error_provider, r=workingjubilee REVERT: cd1c9984d30 Rollup merge of #126468 - RalfJung:euclid, r=Mark-Simulacrum REVERT: 27308799efa Rollup merge of #126346 - hermit-os:fd, r=Amanieu REVERT: ebbce699236 Rollup merge of #126288 - x4exr:patch-1, r=dtolnay REVERT: 4aa43c72385 Auto merge of #125720 - folkertdev:optimize_for_size-ptr-rotate, r=Amanieu REVERT: 791232945c4 doc: Added commas where needed REVERT: 48e157873f1 Fix doc-link issue REVERT: 489dfceabae Remove reliance on const_trait in sort implementations REVERT: 89b578450c9 std: move `sys_common::backtrace` to `sys` REVERT: 90dbe22a287 use rustc-dep-of-std in panic_unwind REVERT: 6832ad31e1c Rollup merge of #126539 - lukaslueg:patch-1, r=jhpratt REVERT: 04e46c2630d Rollup merge of #125112 - tbu-:pr_create_dir_all_empty, r=dtolnay REVERT: e77b4744b48 Update `Arc::try_unwrap()` docs REVERT: 83c530fb2f8 Apply review comments REVERT: ae7f43eda80 Auto merge of #126299 - scottmcm:tune-sliceindex-ubchecks, r=saethlin REVERT: 339f26630a2 Redo SliceIndex implementations REVERT: 2388743f251 update comment REVERT: 4cc1c37692c Rollup merge of #126229 - ChrisDenton:bindgen, r=Mark-Simulacrum REVERT: b40c54bb5bc std: refactor the TLS implementation REVERT: 7e3c4f82606 Auto merge of #126518 - matthiaskrgr:rollup-wb70rzq, r=matthiaskrgr REVERT: 26785938493 std: suggest OnceLock over Once REVERT: b509ed20612 Polish `std::path::absolute` documentation. REVERT: c3c175798d2 Auto merge of #126473 - matthiaskrgr:rollup-8w2xm09, r=matthiaskrgr REVERT: a135342704a Rollup merge of #126285 - kpreid:unique-rc, r=dtolnay REVERT: 7fafb6d366e Rollup merge of #126266 - tbu-:pr_doc_alloc_default_system, r=jhpratt REVERT: afee9f5e11d Rollup merge of #126135 - hermit-os:fuse, r=jhpratt REVERT: 4a32b4bcf84 Rollup merge of #123769 - dtolnay:literal, r=fee1-dead REVERT: 3909d510924 div_euclid, rem_euclid: clarify/extend documentation REVERT: ca52a2ca0e3 Rollup merge of #126351 - devnexen:to_sol11_upd, r=ChrisDenton REVERT: 369fa557b2f Rollup merge of #126402 - firefighterduck:fix-unsafe-precon-copy, r=Nilstrieb REVERT: 2acb995e558 Rollup merge of #126390 - Kriskras99:master, r=Nilstrieb REVERT: b3c1dcb8a6b Rollup merge of #126360 - compiler-errors:uplift-structural-traits, r=lcnr REVERT: bdb9aa2f3cd Rollup merge of #123726 - jieyouxu:command-new-docs, r=Nilstrieb REVERT: 307d1afdbd4 Remove superfluous escaping from byte, byte str, and c str literals REVERT: 78d94eeb0ff LangItem-ify Coroutine trait in solvers REVERT: 891f00ce0fd fix wrong assert_unsafe_precondition message for core::ptr::copy REVERT: 9adf702cc46 Rollup merge of #126384 - RalfJung:is_none_or, r=workingjubilee REVERT: 02cb1e9e580 Rollup merge of #126347 - slanterns:try_simplify, r=scottmcm REVERT: fa2a54a54c6 Fix wording in {checked_}next_power_of_two REVERT: 3ef894f8bc5 add tracking issue for is_none_or REVERT: a5fe19dc0bd std::unix::fs::link using direct linkat call for Solaris and macOs. REVERT: 9921cd25ed1 Rollup merge of #126328 - RalfJung:is_none_or, r=workingjubilee REVERT: 93583a69853 Simplify `try_*` on `Iterator` REVERT: 47090b15fb8 export std::os::fd module on HermitOS REVERT: 17c90d81d23 Auto merge of #126273 - pietroalbini:pa-bootstrap-update, r=Mark-Simulacrum REVERT: b482e06e29c add is_none_or REVERT: 027c82e6edc Rollup merge of #126322 - m-ou-se:panicinfo-and-panicinfo-2, r=RalfJung REVERT: db03ec6a89e Rollup merge of #126242 - yaahc:simplify-provider, r=jhpratt REVERT: 956efdef025 Rollup merge of #126039 - dpaoliello:arm64ecbuild, r=davidtwco REVERT: 3acb41fba7c Fix deprecated version. REVERT: bc5e618edd3 Update doc comment on PanicInfo::message(). REVERT: 249d63e985c Use payload_as_str instead of two downcasts. REVERT: 15677e9f865 Fix deprecation version. REVERT: a239d5bf0e1 Clarify doc comment. REVERT: 209f8c80d1f Auto merge of #126319 - workingjubilee:rollup-lendnud, r=workingjubilee REVERT: 6ec98e76fb6 Rollup merge of #126305 - workingjubilee:fix-os-string-to-string-utf8-invariant, r=joboet REVERT: 80467da88db Rollup merge of #126287 - nnethercote:reformat-cranelift-patch, r=bjorn3 REVERT: 5760a4e9d4e Rollup merge of #126281 - ChrisDenton:env, r=jhpratt REVERT: 439c2ae36dc Rollup merge of #126249 - workingjubilee:simplify-try-map-signature, r=scottmcm REVERT: 23e3dbf043a Rollup merge of #126210 - lolbinarycat:ptr_doctest_assert, r=workingjubilee REVERT: d46939470bf Rollup merge of #123374 - mgeier:doc-slice-from-raw-parts, r=scottmcm REVERT: 63fe960c257 Require any function with a tait in its signature to actually constrain a hidden type REVERT: e1d73c2d74a Revert "Rollup merge of #125362 - joboet:tait_hack, r=Nilstrieb" REVERT: 382ed528dc8 Make PathBuf less Ok with adding UTF-16 then `into_string` REVERT: 548e7a4135e Update a cranelift patch file for formatting changes. REVERT: 8ccbe9e6c8a `UniqueRc`: support allocators and `T: ?Sized`. REVERT: b3dcee69396 set_env: State the conclusion upfront REVERT: f56c02311ee Rename `std::fs::try_exists` to `std::fs::exists` and stabilize fs_try_exists REVERT: c16d8b1f7a5 Unify guarantees about the default allocator REVERT: d8fe5899dc8 remove cfg(bootstrap) REVERT: a2ff49b68b4 replace version placeholder REVERT: f72e4a99cd5 Formatting. REVERT: 0503ca79148 Bump deprecation of std's PanicInfo alias to 1.82.0. REVERT: fea6b035e61 Add PanicHookInfo::payload_as_str(). REVERT: 0c8a9e06b97 Fix display of panic message in recursive panic. REVERT: 2f85702e572 Mention core's PanicInfo in error.md. REVERT: ad0667f9724 Add note on panic payload type. REVERT: 518722eccfc Downcast panic payload to String too in example. REVERT: c4dea816f7f Move deprecation of std::panic::PanicInfo to 1.80.0. REVERT: 143e4c4a40e Fix deprecation version. REVERT: c6749ae5b90 Rename std::panic::PanicInfo to PanicHookInfo. REVERT: db2e05588c5 Formatting. REVERT: 51f20ac6148 Fix invalid markdown/html. REVERT: d4b7304c0de Reorder body of begin_panic for consistency. REVERT: 373fb60b119 Impl Display for PanicPayload to simplify things. REVERT: 224d45cf15c Use unnamed lifetimes for [..]Payload impl blocks. REVERT: cf984e0e154 Move downcasting panic payload to str to a function. REVERT: a18eeac0a12 Mark some PanicInfo methods as #[inline] for consistency. REVERT: 47f359bc210 Remove std::panic::PanicInfo::internal_constructor+set_payload. REVERT: 701d6a23254 Remove core::panic::PanicInfo::internal_constructor. REVERT: cca865dd137 Update doc comment about core::panicking. REVERT: 221a90ccb77 Fix doc link. REVERT: d6658a5e3dd Add core::panic::PanicInfo::payload() for compatibility. REVERT: ca0bfebc0fe Document difference between core and std's PanicInfo. REVERT: 702405ed414 Split core's PanicInfo and std's PanicInfo. REVERT: 019e01f23f5 Skip fast path for dec2flt when optimize_for_size REVERT: 483f641ee13 Simplify `[T; N]::try_map` signature REVERT: 8b6f468edd8 Simplify provider api to improve llvm ir REVERT: c8170e67b53 Rollup merge of #126212 - SteveLauC:fix/haiku, r=joboet REVERT: 58bb5cfddf4 Rollup merge of #126191 - ivan-shrimp:nonzero_doc, r=scottmcm REVERT: d2f8ddfcc21 Bump windows-bindgen to 0.57 REVERT: 02bf1521553 Clarify `Command::new` behavior if passed programs with arguments REVERT: e17d6b968b4 Remove some unused crate dependencies. REVERT: 5840184c348 Update docs for AtomicU8/I8. REVERT: 87915497e69 fix: build on haiku REVERT: 263861f45c9 Update safety docs for AtomicBool::from_ptr. REVERT: e25ae61e2b5 docs(core): make more const_ptr doctests assert instead of printing REVERT: cf9de23d66b Auto merge of #126205 - jieyouxu:rollup-s64z5ng, r=jieyouxu REVERT: c5da756bc2a Rollup merge of #126194 - ChrisDenton:winerror, r=Mark-Simulacrum REVERT: c4bd74c1902 Rollup merge of #125253 - sunsided:feature/FRAC_1_SQRT_PI, r=Mark-Simulacrum REVERT: c9c5d8f0189 Auto merge of #126193 - RalfJung:miri-sync, r=RalfJung REVERT: e39299d577e Migrate more things to WinError REVERT: 0df0a38c38b fix `NonZero` doctest inconsistencies REVERT: 818933db00d Rollup merge of #126168 - devnexen:current_exe_haiku_simpl, r=ChrisDenton REVERT: a9bd5698ac7 Rollup merge of #126146 - devnexen:signal_fbsd, r=ChrisDenton REVERT: 05812a0309b Merge from rustc REVERT: 56bdaf3dfb3 std::unix::os current_exe implementation simplification for haiku. REVERT: e6c378f9a8e Auto merge of #125966 - schvv31n:impl_os_string_pathbuf_leak, r=workingjubilee REVERT: e000ecbd84a std::unix::process adding few specific freebsd signals to be able to id. REVERT: 67454f58555 Rollup merge of #126138 - wbk:patch-1, r=lqd REVERT: ca932c80555 Rollup merge of #125998 - devnexen:get_mode_illumos, r=Nilstrieb REVERT: 397e9cbe400 Rollup merge of #125951 - slanterns:error_in_core_stabilization, r=Amanieu REVERT: 4655eca9735 Fix typo in docs for std::pin REVERT: bb2e2d9fc7d add HermitOS support of vectored read/write operations REVERT: dd7ccb77633 Rollup merge of #126089 - wutchzone:option_take_if, r=scottmcm REVERT: 199da77e638 Rollup merge of #126030 - ChrisDenton:update-wingen-readme, r=Mark-Simulacrum REVERT: 8a4b11aa65d Rollup merge of #124012 - slanterns:as_slice_stabilize, r=BurntSushi REVERT: 05a92c2d02b Auto merge of #126110 - workingjubilee:backtrace-0.3.73, r=workingjubilee REVERT: cd73cbea88a Update backtrace to 0.3.73 REVERT: c6e53ce2b1a Merge from rustc REVERT: 3b603356225 Rollup merge of #125606 - diondokter:opt-size-int-fmt, r=cuviper REVERT: 7014731c32e fix doc comments about `error_generic_member_access` REVERT: 3f4816887c7 Stabilize `error_in_core` REVERT: 20f15f4d41a fixed memory leaks in PathBuf::leak & OsString::leak tests REVERT: fa66a61d655 Rollup merge of #126096 - c410-f3r:tests-tests-tests, r=jhpratt REVERT: 57369442f0d [RFC-2011] Allow `core_intrinsics` when activated REVERT: dfddd7e5a86 Stabilize Option::take_if REVERT: dbbb4ab477a less garbage, more examples REVERT: 051c6c60977 Raise `DEFAULT_MIN_STACK_SIZE` to at least 64KiB REVERT: 29932f32723 Auto merge of #126038 - matthiaskrgr:rollup-h4rm3x2, r=matthiaskrgr REVERT: 149a2370c6e Promote `arm64ec-pc-windows-msvc` to tier 2 REVERT: 4a81c121a38 Rollup merge of #126032 - ChrisDenton:update-docs, r=joboet REVERT: 7450cf043b4 Rollup merge of #125800 - fortanix:raoul/rte-99-fix_mut_static_task_queue, r=jethrogb REVERT: ed91d5578b4 Rollup merge of #125940 - devnexen:unix_fs_netbsd_get_path, r=cuviper REVERT: bf7430fdc68 Update description of the `IsTerminal` example REVERT: 91c8b231664 Update `./x fmt` command REVERT: 16321651051 Rollup merge of #125995 - kpreid:const-uninit-stable, r=Nilstrieb REVERT: 2c5f1acc4c1 Rollup merge of #125982 - xTachyon:fix-linked-list, r=jhpratt REVERT: 80cee25cbad Rollup merge of #123168 - joshtriplett:size-of-prelude, r=Amanieu REVERT: 28dc012bfbf std::unix::fs::get_mode implementation for illumos/solaris. REVERT: 14a6f295bcd Use inline const instead of unsafe to implement `MaybeUninit::uninit_array()`. REVERT: a2c3406e626 Use inline const instead of unsafe to construct arrays in `MaybeUninit` examples. REVERT: f8ee355f9c4 Rollup merge of #125932 - schvv31n:patch-1, r=lqd REVERT: 49dad463287 Rollup merge of #125927 - ferrocene:lw-alloc-unwind-test, r=pietroalbini REVERT: e38c13a5962 Rollup merge of #125696 - workingjubilee:please-dont-say-you-are-lazy, r=Nilstrieb REVERT: 1764910ce42 Rollup merge of #106186 - rossmacarthur:ft/iter-chain, r=Amanieu REVERT: fbb5246b92c Make deleting on LinkedList aware of the allocator REVERT: 85aa4b6ae53 impl OsString::leak & PathBuf::leak REVERT: b19dd145ea9 Add function `core::iter::chain` REVERT: 4952644d73e update tracking issue for `const_binary_heap_new_in` REVERT: 25245bba3d9 Rollup merge of #125919 - tbu-:pr_fix_typo, r=lqd REVERT: a415dddaa0d Rollup merge of #125504 - mqudsi:once_nominal, r=cuviper REVERT: ea7e91c6357 Let compiler auto impl `Send` for `Task` REVERT: 55f3d10071c Store `Task::p` as `dyn FnOnce() + Send` REVERT: 92b604f475f Pass function for `Thread` as `Send` to `Thread::imp` REVERT: 33389b0e051 more explicitly state the basic rules of working with the obtained raw pointers REVERT: 395ad9f8afc Windows: Use futex implementation for `Once` REVERT: 175ad227af0 Auto merge of #125525 - joboet:tls_accessor, r=cuviper REVERT: 31e0022e8f2 std::unix::fs::get_path: using fcntl codepath for netbsd instead. REVERT: 82e24ad44cd Fix typo in the docs of `HashMap::raw_entry_mut` REVERT: fcc07af4e3a Ignore `vec_deque_alloc_error::test_shrink_to_unwind` test on non-unwind targets REVERT: 6ef46b31227 Auto merge of #125912 - nnethercote:rustfmt-tests-mir-opt, r=oli-obk REVERT: 79271381c4f Remove stray "this" REVERT: 06d9b0e9397 Add "OnceList" example to motivate OnceLock REVERT: 6d001c57db6 Move first OnceLock example to LazyLock REVERT: 7e47256ddbf Differ LazyLock vs. OnceLock in std::sync overview REVERT: a198721997c Explain LazyCell in core::cell overview REVERT: ae5598aabc3 Reformat `mir!` macro invocations to use braces. REVERT: 494f05c1d78 Rollup merge of #125898 - RalfJung:typo, r=Nilstrieb REVERT: 7881d33deef Rollup merge of #125884 - Rua:integer_sign_cast, r=Mark-Simulacrum REVERT: 380d9a3d410 Rollup merge of #121062 - RustyYato:f32-midpoint, r=the8472 REVERT: 81b9e26560b Wording of the documentation REVERT: 1c707b64249 typo: depending from -> on REVERT: fe5adb924fb Auto merge of #125577 - devnexen:netbsd_stack_min, r=joboet REVERT: 7953644ecec from_ref, from_mut: clarify domain of quantification REVERT: 876458ec8a2 Implement feature `integer_sign_cast` REVERT: e929c7fda65 Change f32::midpoint to upcast to f64 REVERT: cd0400080d5 Auto merge of #124294 - tspiteri:ilog-first-iter, r=the8472 REVERT: 7f0b19dd24d stablize `const_binary_heap_constructor` & create an unstable feature `const_binary_heap_new_in` for `BinaryHeap::new_in` REVERT: 5c2e2744f32 Rollup merge of #125730 - mu001999-contrib:clippy-fix, r=oli-obk REVERT: 9fe18037b50 Auto merge of #124662 - zetanumbers:needs_async_drop, r=oli-obk REVERT: 894310362d5 Avoid `mut` and simplify initialization of `TASK_QUEUE` REVERT: ba98164a104 Auto merge of #124636 - tbu-:pr_env_unsafe, r=petrochenkov REVERT: bbaaa79ab59 Rollup merge of #125746 - jmillikin:duration-from-weeks-typo, r=lqd REVERT: 1329a62eb9e Rollup merge of #125739 - RalfJung:drop-in-place-docs, r=workingjubilee REVERT: 8883bcf630b Rollup merge of #125342 - tbu-:pr_doc_write, r=ChrisDenton REVERT: 14d5dcb4160 explain what the open questions are, and add a Miri test for that REVERT: 6f01ba7ade6 Apply x clippy --fix and x fmt REVERT: c9c0713ee9b Fix copy-paste error in `Duration::from_weeks` panic message. REVERT: e935223b1b8 Rollup merge of #125733 - compiler-errors:async-fn-assoc-item, r=fmease REVERT: 4feb8819521 Elaborate about modifying env vars in multi-threaded programs REVERT: 25007197aef Add note about safety of `std::env::set_var` on Windows REVERT: c4b1ff893a1 Make `std::env::{set_var, remove_var}` unsafe in edition 2024 REVERT: 07d3009644f drop_in_place: weaken the claim of equivalence with drop(ptr.read()) REVERT: 99eabb47fb4 Add lang item for AsyncFnKindHelper::Upvars REVERT: a8f468f97f8 Add lang item for Future::Output REVERT: 2e1896e1976 Add lang items for AsyncFn's associated types REVERT: d82378a11dd [ACP 362] genericize `ptr::from_raw_parts` REVERT: 619e33b0691 Add FRAC_1_SQRT_2PI doc alias to FRAC_1_SQRT_TAU REVERT: 12652447f15 make `ptr::rotate` smaller when using `optimize_for_size` REVERT: bb6d4eb5be6 Add safety comment to fix tidy REVERT: c8b699c1ab2 Optimize async drop glue for some old types REVERT: 0444ab852cd Add FRAC_1_SQRT_2PI constant to f16/f32/f64/f128 REVERT: 1aaf0a9adac Rollup merge of #125226 - madsmtm:fix-mac-catalyst-tests, r=workingjubilee REVERT: 565dce2d3fe Rollup merge of #124251 - scottmcm:unop-ptr-metadata, r=oli-obk REVERT: a4025eba8f9 Add custom mir support for `PtrMetadata` REVERT: 87b9f244814 Add an intrinsic for `ptr::metadata` REVERT: 914d2c03f3a Rollup merge of #125637 - nnethercote:rustfmt-fixes, r=GuillaumeGomez REVERT: 3170156cbf5 Make more of the test suite run on Mac Catalyst REVERT: 9753338652f Disable stack overflow handler tests on iOS-like platforms REVERT: 35483898acf Don't format `tests/run-make/*/rmake.rs`. REVERT: 6fcf1300f8b Rollup merge of #125647 - tspiteri:track-lazy_cell_consume, r=workingjubilee REVERT: 385e1b87512 Rollup merge of #125551 - clarfonthey:ip-bits, r=jhpratt REVERT: 457f5eebf4b update tracking issue for lazy_cell_consume REVERT: 893db811403 Auto merge of #125636 - workingjubilee:bump-backtrace-0.3.72, r=workingjubilee REVERT: 67858588bb6 Sync libstd deps with backtrace REVERT: b2148722d86 Bump backtrace to 0.3.72 REVERT: 0ef7706b6c1 Auto merge of #125609 - diondokter:opt-size-char-count, r=thomcc REVERT: 3578f429478 Rollup merge of #124870 - Lokathor:update-result-docs, r=dtolnay REVERT: d4fb66bf7aa Always use the general case char count REVERT: 1e8098b6dd4 Size optimize int formatting REVERT: a74509c7872 Rollup merge of #125559 - scottmcm:simplify-shift-ubcheck, r=workingjubilee REVERT: bc346a0aedb Auto merge of #122079 - tbu-:pr_copy_file_range_probe, r=the8472 REVERT: fdcee4d0921 std::pal::unix::thread fetching min stack size on netbsd. REVERT: d14171db7a1 Auto merge of #125574 - matthiaskrgr:rollup-1oljoup, r=matthiaskrgr REVERT: 3e545bcb6f3 Rollup merge of #125571 - tesuji:dummy-pi, r=Nilstrieb REVERT: 840944248ea Rollup merge of #125561 - Cyborus04:stabilize-slice-flatten, r=scottmcm REVERT: 8981ee4ff26 Auto merge of #125570 - tesuji:stdout-handle, r=Nilstrieb REVERT: addaaed02ce f32: use constants instead of reassigning a dummy value as PI REVERT: 8a6d10d57b7 use proper name instead of magic number REVERT: 64671fa9e4b Stabilize `slice_flatten` REVERT: 40140819538 Auto merge of #125070 - tbu-:pr_set_extension_panic, r=jhpratt REVERT: f54c5577ff7 Auto merge of #125518 - saethlin:check-arguments-new-in-const, r=joboet REVERT: a4bac2bc347 It seems that anchor names are implicitly all lowercase REVERT: 7cddfd46930 Simplify the `unchecked_sh[lr]` ub-checks a bit REVERT: 805f56b8e16 Fix URL target, it's in the module not the type. REVERT: 3b77f19a9a8 github showed that weird. REVERT: 65726c04182 correct for copy paste errors when fixing wrapping. REVERT: 613145f6c4e Resolve https://github.com/rust-lang/rust/pull/124870#issuecomment-2128824959 REVERT: 9677b7057a8 revert to the inconsistent paragraph wrapping. REVERT: bf3ca983d95 Rollup merge of #124667 - newpavlov:stabilize_div_duration, r=jhpratt REVERT: 4af28c44c31 Rollup merge of #123803 - Sp00ph:shrink_to_fix, r=Mark-Simulacrum REVERT: 79e1daf6925 Rollup merge of #122986 - taiki-e:aix-c-char, r=Mark-Simulacrum REVERT: 0b13a6c1235 Rollup merge of #121377 - pitaj:lazy_cell_fn_pointer, r=dtolnay REVERT: b1ac7da4a90 Stabilise ip_bits feature REVERT: 23bb5bc4f4f Auto merge of #121571 - clarfonthey:unchecked-math-preconditions, r=saethlin REVERT: c11b36abf02 Rollup merge of #125527 - programmerjake:patch-2, r=workingjubilee REVERT: d6812d57a9e Rollup merge of #125498 - zmodem:avx512er, r=workingjubilee REVERT: f52291bef6b Rollup merge of #125478 - Urgau:check-cfg-config-bump-stage0, r=Mark-Simulacrum REVERT: 38dcab941d6 Rollup merge of #125271 - RalfJung:posix_memalign, r=workingjubilee REVERT: 29a1b3b9ffd Move the checks for Arguments constructors to inline const REVERT: 5257f3f01ac Add manual Sync impl for ReentrantLockGuard REVERT: 078095a8b94 std: make TLS accessors closures that return pointers REVERT: 567096dab49 Rollup merge of #125497 - meesfrensel:patch-1, r=calebzulawski REVERT: 88f01060642 Auto merge of #125499 - matthiaskrgr:rollup-84i5z5w, r=matthiaskrgr REVERT: dd828cf426c Stop using the avx512er and avx512pf x86 target features REVERT: 749b3766746 Change pedantically incorrect OnceCell/OnceLock wording REVERT: 50f0fa2e235 Rollup merge of #125477 - nnethercote:missed-rustfmt, r=compiler-errors REVERT: eaee1cdb4f2 Rollup merge of #125455 - blyxyas:opt-clamp, r=joboet REVERT: 2b1602ae72f Fix some SIMD intrinsics documentation REVERT: 5af5f810520 Auto merge of #122494 - joboet:simplify_key_tls, r=m-ou-se REVERT: a3658901754 Auto merge of #121150 - Swatinem:debug-ascii-str, r=joboet REVERT: 30b5a70b553 std: clean up the TLS implementation REVERT: 3489d4a3099 std: simplify key-based thread locals REVERT: 99a4928cbe3 Auto merge of #125479 - scottmcm:validate-vtable-projections, r=Nilstrieb REVERT: dfd5a535192 Validate the special layout restriction on DynMetadata REVERT: 59b5617f8ce Remove now outdated comment since we bumped stage0 REVERT: 6fbd5f4643a Run rustfmt on files that need it. REVERT: 1fce3b3766b Auto merge of #125463 - GuillaumeGomez:rollup-287wx4y, r=GuillaumeGomez REVERT: 6d1cdb564d6 Add assert_unsafe_precondition to unchecked_{add,sub,neg,mul,shl,shr} methods REVERT: 2e4649525ca Auto merge of #123724 - joboet:static_tls, r=m-ou-se REVERT: e14d82458f5 Rollup merge of #125452 - Urgau:check-cfg-libraries-cleanup, r=bjorn3 REVERT: a581126333d Rollup merge of #125362 - joboet:tait_hack, r=Nilstrieb REVERT: 1903afc49de Auto merge of #125456 - fmease:rollup-n8608gc, r=fmease REVERT: 05754b8862f Process a single not-ASCII-printable `char` per iteration REVERT: 07f94cbbc6b Rollup merge of #124389 - CensoredUsername:master, r=petrochenkov REVERT: df45c5ffff5 Auto merge of #117804 - saethlin:no-recursive-panics, r=joboet REVERT: 87c3913a42c Make clamp inline REVERT: ba934ca9a2b Copy core/alloc check-cfg message also in std REVERT: 339f74947ea Move some expected cfgs to std build.rs as per Cargo recommandation REVERT: fb68dc3e935 Replace fake "restricted-std" Cargo feature by custom cfg REVERT: f250e00abc0 panic_nounwind in Arguments::new* instead of recursing REVERT: 0606c046ba6 Expect any feature cfg in core and std crates REVERT: 200bc14b638 std: rewrite native thread-local storage REVERT: 0c289fbf2a5 core: use `Copy` in TAIT to fix clippy lint REVERT: 8eaf7855ace Rollup merge of #125392 - workingjubilee:unwind-a-problem-in-context, r=Amanieu REVERT: de824e83a34 Rollup merge of #125156 - zachs18:for_loops_over_fallibles_behind_refs, r=Nilstrieb REVERT: 0e6a8cdbefb Auto merge of #125423 - fmease:rollup-ne4l9y4, r=fmease REVERT: b5a5583aa95 Rollup merge of #125043 - RalfJung:ref-type-safety-invariant, r=scottmcm REVERT: 2d5dc612b03 Rollup merge of #125296 - tesuji:checkcfg-buildstd, r=Nilstrieb,michaelwoerister REVERT: 1525484f4d0 Rollup merge of #124896 - RalfJung:miri-intrinsic-fallback, r=oli-obk REVERT: 074b6e06d75 Auto merge of #117329 - RalfJung:offset-by-zero, r=oli-obk,scottmcm REVERT: 94bb282e242 Wrap Context.ext in AssertUnwindSafe REVERT: 376bf965f88 improve comment wording REVERT: aa2aa238d7e tidy alphabetica REVERT: 27067086648 addresss reviews REVERT: 5fd639cbb32 Update check-cfg lists for std REVERT: 9d4f5b433a2 Update check-cfg lists for alloc REVERT: edd27e234c9 Update check-cfg lists for core REVERT: 83ca47e3269 core: actually use TAIT instead of emulating it REVERT: ce29159a108 Simplify environment variable examples REVERT: 725b38e46aa Auto merge of #125358 - matthiaskrgr:rollup-mx841tg, r=matthiaskrgr REVERT: 9a4c4c87d1a Rollup merge of #125348 - tbu-:pr_doc_path_absolute, r=jhpratt REVERT: 8032a1a27b6 Rollup merge of #125266 - workingjubilee:stream-plastic-love, r=RalfJung,nikic REVERT: eef1bb84e54 Rollup merge of #125225 - madsmtm:ios-crt_externs.h, r=workingjubilee REVERT: b20fc81d540 Rollup merge of #125011 - diondokter:opt-for-size, r=Amanieu,kobzol REVERT: 45acd46951f Auto merge of #124097 - compiler-errors:box-into-iter, r=WaffleLapkin REVERT: 8fa3f607e33 Document behavior of `create_dir_all` wrt. empty path REVERT: fd9af8b62e3 Implement BOXED_SLICE_INTO_ITER REVERT: a398018ee01 Add the impls for Box<[T]>: IntoIterator REVERT: dc3424e8f21 Rollup merge of #125333 - hermit-os:fuse, r=workingjubilee REVERT: 7142c42f289 Rollup merge of #125123 - a1phyr:fix-read_exact, r=workingjubilee REVERT: bab1aed8253 Rollup merge of #124050 - saethlin:less-sysroot-libc, r=ChrisDenton REVERT: be748b645d6 Small fixes to `std::path::absolute` docs REVERT: c0ee0c7948c switch also the default implementation for read_vectored REVERT: dd196e7c132 Document platform-specifics for `Read` and `Write` of `File` REVERT: 57347f2a1b2 switch to the default implementation of `write_vectored` REVERT: a408318fc9a Remove Windows dependency on libc REVERT: da656ae2ac8 Address review comments REVERT: a71d9d9f8e9 Fix c_char on AIX REVERT: 67271309ef4 Rollup merge of #125283 - zachs18:arc-default-shared, r=dtolnay REVERT: 93ac8fe8f67 Switch to primarily using `&str` REVERT: 33cdd89c72f Introduce printable-ASCII fast-path for `impl Debug for str` REVERT: 6973e37fc5f Add a fast-path to `Debug` ASCII `&str` REVERT: e7eba09123b Write `char::DebugEscape` sequences using `write_str` REVERT: ae94e59551c Auto merge of #125313 - matthiaskrgr:rollup-65etxv0, r=matthiaskrgr REVERT: d65aacc2ae6 Rollup merge of #125093 - zachs18:rc-into-raw-with-allocator-only, r=Mark-Simulacrum REVERT: 529d2f27182 Auto merge of #124560 - madsmtm:update-libc, r=Mark-Simulacrum REVERT: 7d0c6cf5266 Make NULL check in argument parsing the same on all unix platforms REVERT: cc937f3207c Auto merge of #123878 - jwong101:inplacecollect, r=jhpratt REVERT: 3a5f258f015 Rollup merge of #124992 - foresterre:example/is-terminal, r=ChrisDenton REVERT: 625f7c39d9c Rollup merge of #124948 - blyxyas:remove-repeated-words, r=compiler-errors REVERT: ce3db1b638a fix typo REVERT: 06f98cb53c4 Fix typo in assert message REVERT: 68bd71a03aa cfg-out unused code under no_global_oom_handling REVERT: bc89bd03ded fmt REVERT: 7e59233a60c Add example to IsTerminal::is_terminal REVERT: 7bdc025f3f9 Auto merge of #123786 - a1phyr:cursor_unsafe, r=joboet REVERT: 44037db2ae3 Fix stacked borrows violation REVERT: 1920ed9058b Use a single static for all default slice Arcs. REVERT: 0ed8a018153 Rollup merge of #125252 - beetrees:patch-1, r=joboet REVERT: 2dcefb792df Rollup merge of #124304 - hermit-os:fuse, r=joboet REVERT: fb9b5c4efde Rollup merge of #123709 - tgross35:windows-cmd-docs-update, r=ChrisDenton REVERT: 49138842df5 use posix_memalign on most Unix targets REVERT: 5df616a99cc Auto merge of #124640 - Billy-Sheppard:master, r=dtolnay REVERT: cfaf50022ea Add NULL check in argument parsing on Apple platforms REVERT: b3ed7df1198 Auto merge of #99969 - calebsander:feature/collect-box-str, r=dtolnay REVERT: 8bbbc353f7a compiler: add simd_ctpop intrinsic REVERT: c8f44c3500d use `Result::into_ok` on infallible result. REVERT: 6e066ce3c43 specialize `Iterator::fold` for `vec::IntoIter` REVERT: 7479403773d optimize in_place_collect with vec::IntoIter::try_fold REVERT: 811303f34cc optimize in-place collection of `Vec` REVERT: f5c17c8513e Rollup merge of #125251 - jonhoo:patch-1, r=Nilstrieb REVERT: bd2c0a2d2a2 Clarify how String::leak and into_boxed_str differ REVERT: ee7954d55c9 Fix typos (taking into account review comments) REVERT: ceaf2051f00 Add `#[inline]` to float `Debug` fallback used by `cfg(no_fp_fmt_parse)` REVERT: e3f681ebd02 android: use posix_memalign for aligned allocations REVERT: bbc5d731171 Add a warning to Delimiter::None that rustc currently does not respect it. REVERT: 65de37a5ec5 Inline Duration construction into Duration::from_{millis,micros,nanos} REVERT: 561b61ae6e1 Update libc to 0.2.155 REVERT: 43505500028 Use `_NSGetArgc`/`_NSGetArgv` on iOS/tvOS/watchOS/visionOS REVERT: 30e2e43ffd9 Use `_NSGetEnviron` instead of `environ` on iOS/tvOS/watchOS/visionOS REVERT: e703bb11006 Don't call Duration::new unnecessarily in Duration::from_secs REVERT: b30cbc8f8ad Auto merge of #125188 - tgross35:f16-f128-powi, r=Nilstrieb REVERT: 8dd9e072080 Rollup merge of #125186 - Colepng:master, r=lqd REVERT: 27c7709e6a8 Rollup merge of #125171 - scottmcm:rename-flatten, r=jhpratt REVERT: 4fc7740a216 Access alloc field directly in Arc/Rc::into_raw_with_allocator. REVERT: c26086e162a Auto merge of #125163 - ssukanmi:stdarch_arm_crc32, r=Amanieu REVERT: 38e61a0cd9e Add `powi` to `f16` and `f128` REVERT: 8f57068184b Add doctests for f16 and f128 library functions where possible REVERT: 4515461d9b8 Remove duplicate word from addr docs REVERT: 266f7a3a84d Auto merge of #124728 - beetrees:from-f16-for-f64, r=BurntSushi REVERT: 86878b964b1 Fix linkchecker doc errors REVERT: 1bf7a30d31a Turn bare links into automatic links REVERT: 736b2250797 Move BufGuard impl outside of function REVERT: a44e7b3adea Fix tidy errors REVERT: 36af6395634 Replace sort implementations REVERT: 4313a19fb79 Auto merge of #124959 - prorealize:update-result-documentation, r=joboet REVERT: 8fb10ab34e0 Rename `flatten(_mut)` → `as_flattened(_mut)` REVERT: 5051ef5f531 Rollup merge of #125003 - RalfJung:aligned_alloc, r=cuviper REVERT: 136dbc3c526 feat: update stdarch submodule for intrinsics on ARM REVERT: 883d0d924b0 Allow for_loops_over_fallibles in test that tests &mut Result as IntoIterator. REVERT: 6b32f28106b Rollup merge of #125038 - ivan-shrimp:checked_sub, r=joboet REVERT: fee95d4f505 Rollup merge of #124307 - reitermarkus:escape-debug-size-hint-inline, r=joboet REVERT: ae1cb832cb6 Update library/core/src/result.rs REVERT: 48a835b093a Divide float nanoseconds instead of seconds REVERT: 9a851b20a22 avoid using aligned_alloc; posix_memalign is better-behaved REVERT: 4cb203b1da4 Fix `read_exact` and `read_buf_exact` for `&[u8]` and `io:Cursor` REVERT: 09663fe5933 Rollup merge of #116675 - joshlf:patch-10, r=scottmcm REVERT: 1e7fecbfef0 Add fn into_raw_with_allocator to Rc/Arc/Weak. REVERT: 7b24df0047d Forward alloc features to core REVERT: 14deb328fd3 Rollup merge of #123817 - slanterns:seek_relative, r=dtolnay REVERT: f84d57f6cc3 Don't use `T` with both Result and Option, improve explanation. REVERT: 88338ff820a Add `size_of`, `size_of_val`, `align_of`, and `align_of_val` to the prelude REVERT: 5d56638742b Panic if `PathBuf::set_extension` would add a path separator REVERT: 05e74fce7d0 offset, offset_from: allow zero-byte offset on arbitrary pointers REVERT: d8853f8e443 Use shared statics for the ArcInner for Arc::default, and for Arc<[T]>::default where alignof(T) <= 16. REVERT: a5d075794b0 Add note about possible allocation-sharing to Arc/Rc::default. REVERT: 22bf3672e03 added Default impls REVERT: 09d9a3b2344 Auto merge of #125045 - GuillaumeGomez:rollup-em6qdzw, r=GuillaumeGomez REVERT: 8d7b24b36d0 Rollup merge of #125021 - joshlf:patch-11, r=RalfJung REVERT: 42c03b9b38a Auto merge of #124798 - devnexen:illumos_memalign_fix, r=RalfJung REVERT: adaf5214346 Auto merge of #125012 - RalfJung:format-error, r=Mark-Simulacrum,workingjubilee REVERT: 5241e407dc1 reference type safety invariant docs: clarification REVERT: b0c4bae2a9b reverse condition in `uN::checked_sub` REVERT: 367de08f6fa Rollup merge of #124981 - zachs18:rc-allocator-generalize-1, r=Mark-Simulacrum REVERT: c195fa04253 References must also be non-null REVERT: 36a981688e2 Relax slice safety requirements REVERT: 6c546e7e8a3 std::alloc: using posix_memalign instead of memalign on solarish. REVERT: 08c5880b820 Auto merge of #124213 - rust-lang:cargo_update, r=Mark-Simulacrum REVERT: b7519610dc3 Pin libc back to 0.2.153 REVERT: 5aa269a0108 io::Write::write_fmt: panic if the formatter fails when the stream does not fail REVERT: f596a68a415 Add flag to sysroot REVERT: 6ccf84a4aa8 Add flag to std and alloc too REVERT: 985bd7c5d18 Add opt-for-size core lib feature flag REVERT: 388e37a9498 Rollup merge of #124954 - kpreid:fmterr, r=Nilstrieb REVERT: c381e255df9 Rollup merge of #124928 - okaneco:trim_ascii, r=workingjubilee REVERT: b63b13f33d4 Rollup merge of #124991 - Infinixius:patch-1, r=Nilstrieb REVERT: 6f9c0775da2 Rollup merge of #124766 - devnexen:getrandom_solarish, r=Mark-Simulacrum REVERT: 0d33b4bf4dd Stabilize `byte_slice_trim_ascii` for `&[u8]`/`&str` REVERT: 9a1eb1e2050 Fix typo in ManuallyDrop's documentation REVERT: 960e8ab70e2 Relax A: Clone requirement on Rc/Arc::unwrap_or_clone. REVERT: bc074ab412e Relax allocator requirements on some Rc APIs. REVERT: 7db52fca9b3 Add fn allocator method to rc/sync::Weak. Relax Rc/Arc::allocator to allow unsized T. REVERT: 378c8fc9804 Auto merge of #124863 - DaniPopes:from-str-radix-panic, r=Amanieu REVERT: 86719215259 Fix assert REVERT: 8c54418f536 Auto merge of #124774 - the8472:subnanosecond-benches, r=jhpratt REVERT: 54be5488e0e Rollup merge of #124551 - Swatinem:debug-str-bench, r=cuviper REVERT: 222895b053e Refactor examples and enhance documentation in result.rs REVERT: fa63eff9805 Document proper usage of `fmt::Error` and `fmt()`'s `Result`. REVERT: 43bf016caa3 Suggest borrowing on fn argument that is `impl AsRef` REVERT: 382db29c362 Auto merge of #124773 - Marcondiro:master, r=joboet REVERT: 21100234707 Improve escape methods. REVERT: 24f4b5121d0 Auto merge of #124793 - scottmcm:simplify-as-chunks, r=Nilstrieb REVERT: 4399b9ebdd7 Auto merge of #124910 - matthiaskrgr:rollup-lo1uvdn, r=matthiaskrgr REVERT: a7f8f81e3fe Rollup merge of #124892 - jfgoog:update-cc, r=workingjubilee REVERT: 37f66ba2889 Avoid panicking branch in `EscapeIterInner`. REVERT: b8826854a39 Inline `EscapeDebug::size_hint`. REVERT: 19ae86b1d3d Auto merge of #124795 - scottmcm:simplify-slice-from-raw-parts, r=joboet REVERT: efc7b04b3ef Use generic `NonZero`. REVERT: 091b42eb014 Use generic `NonZero` in examples. REVERT: d51ea4b068e miri: rename intrinsic_fallback_checks_ub to intrinsic_fallback_is_spec REVERT: 7a07503ee21 Update cc crate to v1.0.97 REVERT: bb9678aaf93 fix #124714 str.to_lowercase sigma handling REVERT: c567ea1a23c Rollup merge of #124838 - RalfJung:next_power_of_two, r=scottmcm REVERT: 8d51e8508f9 Rollup merge of #124788 - madsmtm:reduce-target_os-macos, r=workingjubilee REVERT: ce2c4627b13 Rollup merge of #124782 - anatawa12:docs-create-new-already-exists, r=workingjubilee REVERT: 4870ba34a23 Rollup merge of #124470 - devnexen:no_sigpipe_fbsd, r=workingjubilee REVERT: 50d5af44701 use teletype on the attribute name REVERT: 43ae1871a8b Some Result combinations work like an Option. REVERT: a69f31c459b from_str_radix: outline only the panic function REVERT: d0c07aa8677 Move `test_shrink_to_unwind` to its own file. REVERT: d77b1cc251a Fix `VecDeque::shrink_to` UB when `handle_alloc_error` unwinds. REVERT: 6eba9d713ac Auto merge of #124836 - tgross35:const-slice-last-chunk, r=BurntSushi REVERT: 039a5431958 next_power_of_two: add a doctest to show what happens on 0 REVERT: 252441d0952 Correct the const stabilization of `last_chunk` for slices REVERT: f9f006de23d f16::is_sign_{positive,negative} were feature-gated on f128 REVERT: 6a2e422f4b5 Auto merge of #124811 - matthiaskrgr:rollup-4zpov13, r=matthiaskrgr REVERT: 8501809b599 Rollup merge of #124520 - tbu-:pr_create_dir_all_doc, r=Amanieu REVERT: 9a9f3635dd4 Auto merge of #123850 - tspiteri:f16_f128_consts, r=Amanieu REVERT: c6dcb9ded36 std::rand: adding solaris/illumos for getrandom support. REVERT: ba0be73796c Auto merge of #124497 - rytheo:move-std-tests-to-library, r=workingjubilee REVERT: c9041b78068 Avoid a cast in `ptr::slice_from_raw_parts(_mut)` REVERT: 58f261d8bca Implement `as_chunks` with `split_at_unchecked` REVERT: c4e5d54b093 iOS/tvOS/watchOS/visionOS: Improve File Debug impl REVERT: 74f121b381f iOS/tvOS/watchOS/visionOS: Fix reading large files REVERT: 6333ccf0843 iOS/tvOS/watchOS: Fix alloc w. large alignment on older versions REVERT: e16bbb88409 iOS/tvOS/watchOS/visionOS: Set the main thread name REVERT: 4ea3e928541 Apply suggestions from code review REVERT: d8efd5a647e iOS/tvOS/watchOS/visionOS: Default to kernel-defined backlog in listen REVERT: 41ab2856661 add note about `AlreadyExists` to `create_new` REVERT: 7c225d78d9c emit fractional benchmark nanoseconds in libtest's JSON output format REVERT: 6431fc87674 print walltime benchmarks with subnanosecond precision REVERT: 8e59cbf3014 alloc: implement FromIterator for Box REVERT: 456ecae149a Rename test for issue 21058 REVERT: 170468725bd Rollup merge of #124750 - ultrabear:ultrabear_softfloatdoc, r=workingjubilee REVERT: 2f5732c49d6 Rollup merge of #124749 - RossSmyth:stable_range, r=davidtwco REVERT: c738b82af9d Fix unwinding on 32-bit watchOS ARM REVERT: f467aea6d61 Re-add `From for f64` REVERT: 8e7baf3ac32 Make f128 docs mention lack of any normal platform support REVERT: e51d8ac6e03 Make f16 and f128 docs clearer on platform support REVERT: c1f3ead255c Tgross feedback tweaks REVERT: 28d5ede47ba Rollup merge of #124721 - ids1024:netbsd-32-bit-ulong, r=workingjubilee REVERT: 206c2198132 library/std: Fix build for NetBSD targets with 32-bit `c_long` REVERT: 1acfaf2a8bc Rollup merge of #124699 - scottmcm:split_at_unchecked_should_use_unchecked, r=Nilstrieb REVERT: 5bea81c92e2 Rollup merge of #122441 - a1phyr:improve_read_impls, r=ChrisDenton REVERT: 22d57767941 Rollup merge of #124701 - scottmcm:unchecked_sub_docs, r=Nilstrieb REVERT: e63ddd80c40 Rollup merge of #124700 - scottmcm:unneeded_cast, r=Nilstrieb REVERT: 571651c5c4a Rollup merge of #124293 - oli-obk:miri_intrinsic_fallback_body, r=RalfJung REVERT: 8187d388285 Rollup merge of #124159 - joboet:move_pal_thread_parking, r=ChrisDenton REVERT: d8fe9f930e2 Rollup merge of #123356 - joboet:set_current_size, r=ChrisDenton REVERT: a0bfcc320f7 Docs: suggest `uN::checked_sub` instead of check-then-unchecked REVERT: ba13017a305 Remove an unnecessary cast REVERT: b16906dbbe4 Use `unchecked_sub` in `split_at` REVERT: 6b993f55b5b mark const_(de)allocate intrinsics as suitable for Miri REVERT: a8985b9195c Rollup merge of #124681 - risc0:erik/fix-test, r=joboet REVERT: 78978b287c7 Rollup merge of #124678 - UserIsntAvailable:feat/stabilize-split-at-checked, r=jhpratt REVERT: 39b713f9528 Rollup merge of #124480 - Enselic:on-broken-pipe, r=jieyouxu REVERT: be4a2b92e11 feat: stabilize `split_at_checked` REVERT: f748ca30945 Rollup merge of #124593 - GKFX:cstr-literals-in-api-docs, r=workingjubilee REVERT: e103a071226 Rollup merge of #124059 - RalfJung:default_alloc_error_hook, r=workingjubilee REVERT: 2dd44afac42 Rollup merge of #123815 - trueb2:patch-1, r=workingjubilee REVERT: ca6d5db5449 Rollup merge of #122492 - GrigorenkoPV:ptr_as_ref_unchecked, r=workingjubilee REVERT: df5e42c921f default_alloc_error_hook: explain difference to default __rdl_oom in alloc REVERT: 0342284416b Use `CURRENT_RUSTC_VERSION` REVERT: 9eb77db22f6 Stabilize `div_duration` REVERT: 4d19673b6bd Rollup merge of #124649 - Meziu:master, r=ChrisDenton REVERT: d53a5d87abd Ensure miri only uses fallback bodies that have manually been vetted to preserve all UB that the native intrinsic would have REVERT: f5339d58008 Horizon OS: dirfd unavailable REVERT: a31e6861f4d Rollup merge of #124626 - RalfJung:const_eval_select, r=joboet REVERT: 6b924c2d215 Rollup merge of #124609 - RalfJung:float-precision, r=cuviper REVERT: bbf602cf523 Rollup merge of #124604 - Enselic:std-gimli-symbolize, r=workingjubilee REVERT: 22f7c455b85 Rollup merge of #124441 - bravequickcleverfibreyarn:string.rs, r=Amanieu REVERT: ed69db3f9ad Rollup merge of #124412 - RalfJung:io-safety, r=Amanieu REVERT: 29b5199904a Rollup merge of #123480 - Nadrieril:impl-all-derefpures, r=compiler-errors REVERT: a930b12dbbe Stabilize exclusive_range REVERT: 53755c9d24b Update based on review REVERT: dbaecde9672 Change `SIGPIPE` ui from `#[unix_sigpipe = "..."]` to `-Zon-broken-pipe=...` REVERT: 87c17006251 variable-precision float operations behave non-deterministically REVERT: 798d96685ff const_eval_select: add tracking issue REVERT: 57f8e3f6215 add constants in std::f128::consts REVERT: a3caf785466 add constants in std::f16::consts REVERT: 96635050b03 add f128 associated constants REVERT: b90c063cf70 add f16 associated constants REVERT: 08dcd04c27b Auto merge of #124419 - WaffleLapkin:never-type-fallback-docs, r=workingjubilee REVERT: 5420e304749 std: move thread parking to `sys::sync` REVERT: a563923fd8a library/std: Remove unused `gimli-symbolize` feature REVERT: b79f6575858 fixup links in never type docs REVERT: 5f113115560 Workaround rustfmt bug replacing type ascription REVERT: 8f360735eef Slightly reformat !'s docs after applying github suggestions REVERT: 6453de7af31 Step bootstrap cfgs REVERT: d562f4d418d Apply suggestions from code review REVERT: 6754ce4b9b5 Replace version placeholders for 1.79 REVERT: 8b4a654c7da Describe and use CStr literals in CStr and CString docs REVERT: 7f3217e9690 Rollup merge of #124542 - CBSpeir:diagnostic-item-enumerate-method, r=scottmcm REVERT: c45c254f1aa Add benchmarks for `impl Debug for str` REVERT: dda73645a60 Auto merge of #124491 - madsmtm:target_vendor-apple, r=workingjubilee REVERT: 4f147e3ad08 std: rewrite TLS on platforms without threads REVERT: 23224f3d32c Add diagnostic item for std::iter::Iterator::enumerate REVERT: ddf4a17a38b Rollup merge of #124530 - djkoloski:fuchsia_dirfd, r=tmandry REVERT: bb9ac1bed65 Document that `create_dir_all` calls `mkdir`/`CreateDirW` multiple times REVERT: dcd99927e38 Rollup merge of #124484 - GKFX:offset_of_must_use, r=jieyouxu REVERT: 8cec3545621 Fix Fuchsia build broken by #124210 REVERT: 05d627050dc Fix ESP IDF build broken by #124210 REVERT: d43f05d92d9 Auto merge of #124502 - NCGThompson:statically-known-docs, r=jhpratt REVERT: 56d5b84b45f Update is_val_statically_known docs REVERT: 01ac54c964f Run tidy on tests REVERT: 9f4b5068ab7 Stabilize `non_null_convenience` REVERT: 4a2abd366dd Fix posix_spawn not being used on iOS and visionOS REVERT: e7cb5e33051 Move various stdlib tests to library/std/tests REVERT: ae52df677a4 Fix va_list on watchOS and visionOS REVERT: 31d3d1ef5d3 Fix SIGEMT and SIGINFO parsing on watchOS and visionOS REVERT: fb0aa42c804 Fix available_parallelism on watchOS and visionOS REVERT: aef2c4bf523 Fix #124478 - offset_of! returns a temporary REVERT: b3793608a22 std::net: Socket::new_raw set to SO_NOSIGPIPE on freebsd/netbsd/dragonfly. REVERT: d2f0f29a8e2 Use `target_vendor = "apple"` instead of `target_os = "..."` REVERT: 585e7880633 Auto merge of #124210 - the8472:consign-ebadf-to-the-fire, r=Mark-Simulacrum REVERT: fdcf9028e48 put FD validity behind late debug_asserts checking REVERT: 00ddbeef794 Rollup merge of #124447 - workingjubilee:set-argv-twice-on-gnu, r=ChrisDenton REVERT: 48087698a6c Unconditionally call really_init REVERT: 7a6ddb35da6 Lift the probe code of `copy_file_range` into a function REVERT: dd215a8df14 Elaborate in comment about `statx` probe REVERT: 94de29b7814 WS fix. REVERT: 5530b833536 String.truncate calls Vec.truncate, in turn, and that states "is greater or equal to". Beside common sense. REVERT: e43ff272329 Auto merge of #124432 - zetanumbers:non_copy_into_raw_with_alloc, r=Nilstrieb REVERT: b94c1ea3960 Relax `A: Clone` bound for `rc::Weak::into_raw_and_alloc` REVERT: c60c646afcb io safety: update Unix explanation REVERT: bc31aa7193d Rollup merge of #124387 - workingjubilee:use-raw-pointers-in-thread-locals, r=joboet REVERT: e3c3ae33f45 thread_local: refine LazyKeyInner::take safety doc REVERT: 649101a66c3 Rollup merge of #124410 - RalfJung:path-buf-transmute, r=Nilstrieb REVERT: 0cfee71b625 Apply suggestions from code review REVERT: f5305c1c49a Add missing .into_iter() REVERT: 2a5af324d19 Extend the example code and assert the result REVERT: 093b3a7340b Document never type fallback in `!`'s docs REVERT: 678e5a09970 Add "safety" comment REVERT: d83ddf5487c Auto merge of #123909 - dtolnay:utf8chunks, r=joboet REVERT: 0f28de0474e PathBuf: replace transmuting by accessor functions REVERT: 91e6f9d261f Auto merge of #124393 - scottmcm:do-the-macros-still-matter, r=joboet REVERT: dc3de6b3694 Convert some iter macros to normal functions REVERT: cb96ad55b1e Rollup merge of #124076 - NobodyXu:patch-1, r=dtolnay REVERT: 60c92534076 thread_local: split refs to fields of Key REVERT: 4fd95572c93 thread_local: use less &mut T in LazyKeyInner::take REVERT: ad88e3e3d00 remove trivial bounds REVERT: d2c5fb9f9df Stabilize Utf8Chunks REVERT: ad89cf034d8 Rollup merge of #124351 - Treeniks:master, r=workingjubilee REVERT: 72e9d095bf2 Rollup merge of #124335 - ChrisDenton:stabilize-absolute, r=dtolnay REVERT: 3504c1e55e3 Rollup merge of #124322 - whosehang:master, r=Nilstrieb REVERT: 9f98c505623 fix typo in binary_heap docs REVERT: e8578cf3182 Auto merge of #124330 - fmease:rollup-a98y7jf, r=fmease REVERT: fb15b05719f Fix cannot usage in time.rs REVERT: 2a9b748bdfb Stabilize `std::path::absolute` REVERT: e8ea161ce8d Add `cfg_attr(bootstrap)` to doc tests REVERT: e72526a7862 Stabilise `inline_const` REVERT: 0dcdc5d3d1f Rollup merge of #124308 - CBSpeir:diagnostic-item-enumerate, r=compiler-errors REVERT: 58adebb606f Rollup merge of #124282 - RalfJung:fill_utf16_buf, r=ChrisDenton REVERT: fa7cbc4922c Rollup merge of #124281 - RalfJung:win-tls, r=joboet REVERT: 7c70cbbbf3f Error on using `yield` without also using `#[coroutine]` on the closure REVERT: 59b57e9548e chore: fix some typos in comments REVERT: 89e9dd3247d Add diagnostic item for std::iter::Enumerate REVERT: 7e58b1f1fd6 increase the readability by using the unique name for the hermit-abi REVERT: b8dab92c929 Auto merge of #124302 - matthiaskrgr:rollup-2aya8n8, r=matthiaskrgr REVERT: 86d0c93fc7c Rollup merge of #124003 - WaffleLapkin:dellvmization, r=scottmcm,RalfJung,antoyo REVERT: fccc0999ded revise the interpretation of ReadDir REVERT: eb97638cea1 Rollup merge of #123048 - RalfJung:layout, r=dtolnay REVERT: ad38f9b8000 unroll first iter of checked_ilog loop to save one multiplication REVERT: 50a633b3dc5 Rollup merge of #123050 - RalfJung:panic_str, r=m-ou-se REVERT: 2d5d316d0cb fix weak memory bug in TLS on Windows REVERT: ee9b6a66af9 windows fill_utf16_buf: explain the expected return value REVERT: 7a3093ab053 Rollup merge of #124266 - RalfJung:no-answer, r=joboet REVERT: bffc1abb0fa Auto merge of #121801 - zetanumbers:async_drop_glue, r=oli-obk REVERT: 9241efe43e8 Rollup merge of #124230 - reitermarkus:generic-nonzero-stable, r=dtolnay REVERT: 5e43c9e2343 Rollup merge of #115913 - FedericoStra:checked_ilog, r=the8472 REVERT: f68a2540450 remove an unused type from the reentrant lock tests REVERT: 263871761f1 export assert_unsafe_precondition macro for std-internal use REVERT: ddfc171f4d1 Stabilize generic `NonZero`. REVERT: 1e346e3f46a Rollup merge of #124246 - gurry:add-comma-in-abs-doc, r=jhpratt REVERT: 799338151c2 Add comma at one place in `abs()` documentation REVERT: bc9a3bac63d Update stdarch submodule REVERT: 5d3ff3c85b9 Address more PR feedback REVERT: 9dc6454cb12 Use it in the library, and `InstSimplify` it away in the easy places REVERT: 4718ee986d8 Add an intrinsic that lowers to AggregateKind::RawPtr REVERT: 3ecfe74aab9 Rollup merge of #124184 - gurry:124152-suggest-unsigned-abs-in-abs-doc, r=jhpratt REVERT: d11afaba321 Rollup merge of #124089 - simlay:fix-preadv64-and-pwritev64-link-for-watchos-and-visionos, r=workingjubilee REVERT: bab3c02e234 Fix watchOS and visionOS for pread64 and pwrite64 calls REVERT: 1602a46cce6 Auto merge of #123930 - Mark-Simulacrum:vec-length-invariant, r=jhpratt REVERT: 755057b1edc Avoid reloading Vec::len across grow_one in push REVERT: 39144205382 Auto merge of #124208 - jieyouxu:rollup-gbgpu4u, r=jieyouxu REVERT: 3e0bb0d3435 Abort a process when FD ownership is violated REVERT: 15cabd56959 Rollup merge of #124103 - dtolnay:metadatadebug, r=Mark-Simulacrum REVERT: 5a86d4a6510 Rollup merge of #123976 - ChrisDenton:no-libc-in-std-doc-tests, r=Mark-Simulacrum REVERT: 5b55d8707a4 Rollup merge of #123967 - RalfJung:static_mut_refs, r=Nilstrieb REVERT: 63994f74cf8 Auto merge of #122013 - Swatinem:unicode-gen-fastpath, r=scottmcm REVERT: aa25c2f1e6c Add a lower bound check to `unicode-table-generator` output REVERT: d32491fe8a4 Suggest using `unsigned_abs` in `abs` documentation REVERT: ed803c29a95 Auto merge of #124114 - scottmcm:better-checked, r=workingjubilee REVERT: e32c184903f Rollup merge of #124116 - RalfJung:miri-rust-backtrace, r=Nilstrieb REVERT: 63a6950cee6 Rollup merge of #124019 - ChrisDenton:futex-raw-dylib, r=joboet REVERT: 4660cc66f34 Rollup merge of #123406 - krtab:fix_remainder_iterchunk, r=scottmcm REVERT: 2a4abc3cdb0 Make `checked` ops emit *unchecked* LLVM operations where feasible REVERT: c6285016410 Auto merge of #123144 - dpaoliello:arm64eclib, r=GuillaumeGomez,ChrisDenton,wesleywiser REVERT: b079821f1a9 when suggesting RUST_BACKTRACE=1, add a special note for Miri's env var isolation REVERT: b3b8c6d95dd Improve std::fs::Metadata Debug representation REVERT: 9699e68541d fix: make `str::from_raw_parts_mut` mut REVERT: a1dfa797f23 Rollup merge of #124049 - slanterns:const_io_structs_stabilize, r=jhpratt REVERT: 3dc77cf6bf4 Rollup merge of #122201 - coolreader18:doc-clone_from, r=dtolnay REVERT: 720fc75c4c7 Stablise io_error_downcast REVERT: 3a4e1618d09 Address comments REVERT: a05f231cbc6 Rollup merge of #124051 - dtolnay:emptyset, r=compiler-errors REVERT: b12e3b3048d Fix empty-set symbol in comments REVERT: 493080a0281 Stabilize `const_io_structs` REVERT: a86fde379d2 Rollup merge of #124013 - RalfJung:box-to-raw, r=oli-obk REVERT: ffa1ca9d180 Rollup merge of #123859 - krtab:uneeded_clone, r=cuviper REVERT: ac79fe637e8 Rollup merge of #123811 - joboet:queue_em_up, r=ChrisDenton REVERT: e0dc297888d Add simple async drop glue generation REVERT: 8b73e2eb0fa Use raw-dylib for Windows futex APIs REVERT: 84236d9eb78 std: fix lint on SGX REVERT: a783e1008bc Remove uneeded clones now that TrustedStep implies Copy REVERT: bae79d94085 Rollup merge of #123721 - madsmtm:fix-visionos, r=davidtwco REVERT: dbd03d4517e Stabilize `BinaryHeap::as_slice` REVERT: 94853467d7b Box::into_raw: make Miri understand that this is a box-to-raw cast REVERT: 2f18bf025db Update usage note on OpenOptions::append() REVERT: 5a124e4bf0f Change intrinsic types to use `u32` instead of `T` to match stable reexports REVERT: 9b3dfe9b8f5 Add support for Arm64EC to the Standard Library REVERT: 03f665c66d5 Rollup merge of #123970 - risc0:erik/zkvm-fix-os-str, r=joboet REVERT: 9265a3ecc93 Use fake libc in core test REVERT: 94831ffaa3a Auto merge of #123968 - jieyouxu:rollup-1pnkxor, r=jieyouxu REVERT: 311588525c9 static_mut_refs: use raw pointers to remove the remaining FIXME REVERT: 87f16a326ba zkvm: fix references to `os_str` module REVERT: a8ebeb91144 Rollup merge of #123957 - RalfJung:create_dir_all_bare, r=joboet REVERT: 2db449f5918 Rollup merge of #123548 - RalfJung:what-is-time, r=joboet REVERT: 14447a8c9c7 Auto merge of #123937 - RalfJung:miri-link-section, r=oli-obk REVERT: 443a6fbe62c Auto merge of #123851 - NobodyXu:patch-1, r=BurntSushi REVERT: 46ba3f29fe5 Update doc for std::io::Error::downcast REVERT: 21d618464fd Remove bound checks from `BorrowedBuf` and `BorrowedCursor` methods REVERT: 0d1488560ff disable create_dir_all_bare on all(miri, windows) REVERT: f83d4d8991d libtest: also measure time in Miri REVERT: 246b74db31a Auto merge of #123928 - tbu-:pr_statx_enosys, r=workingjubilee REVERT: ff1212e6a22 Add vec_deque::Iter::as_slices and friends REVERT: 5d4f65899c2 Rollup merge of #123915 - shenawy29:patch-1, r=Nilstrieb REVERT: b83291d60fc Rollup merge of #120900 - marcospb19:std-use-seek-stream-position, r=joshtriplett REVERT: e7822c77056 Miri: run .CRT$XLB linker section on thread-end REVERT: 65e3bdb3b05 `statx` probe: `ENOSYS` might come from a faulty FUSE driver REVERT: e4eafca2b1c Auto merge of #122268 - ChrisDenton:no-libc, r=Mark-Simulacrum REVERT: 931580539b0 improve documentation slightly regarding some pointer methods REVERT: 25f46638c83 Move msvc libs to core REVERT: 97543b75e3e Replace libc::c_int with core::ffi::c_int REVERT: 01fea39a003 Rollup merge of #123879 - beetrees:missing-unsafe, r=Mark-Simulacrum REVERT: b6684584739 Rollup merge of #123875 - Ghamza-Jd:master, r=joboet REVERT: 20551dbdc37 Rollup merge of #123779 - semarie:notgull-openbsd-socket, r=Mark-Simulacrum REVERT: 96e9022361a Rollup merge of #123651 - tgross35:thread-local-updates, r=Mark-Simulacrum REVERT: 5055f25b945 Auto merge of #107462 - WaffleLapkin:from_iterator_for_tuple, r=dtolnay REVERT: c4e56d60c18 Auto merge of #123819 - joboet:fmt_usize_marker, r=Mark-Simulacrum REVERT: 61b9833b435 Rollup merge of #123876 - dpaoliello:backtrace, r=ChrisDenton REVERT: aeb4efaa7f0 Rollup merge of #123716 - Kriskras99:patch-2, r=Mark-Simulacrum REVERT: 3cc56ecd90d doc note that f16 and f128 hardware support is limited REVERT: de405577055 Rollup merge of #123868 - eduardosm:stabilize-slice_ptr_len, r=jhpratt REVERT: ed296750a27 Rollup merge of #123835 - saethlin:vec-from-nonnull, r=the8472 REVERT: c1b11248200 Add missing `unsafe` to internal `std::thread::Thread` creation functions REVERT: 5cc2d7b9acc Add missing `unsafe` to internal function `std::sys::pal::unix::thread::min_stack_size` REVERT: f3c1c93e3b5 Update backtrace submodule REVERT: 99e9da1b47a chore: replace x with y for hexa-decimal fmt REVERT: 1f25e2afc2f Avoid more NonNull-raw-NonNull roundtrips in Vec REVERT: 4ad58e6171a Rollup merge of #123867 - eduardosm:unsafe-fns, r=ChrisDenton REVERT: 369308bd980 Rollup merge of #123858 - marijanp:fix-zkvm-cmath-path, r=joboet REVERT: 903bde7926c Rollup merge of #123857 - devnexen:tcp_listener_update_backlog, r=ChrisDenton REVERT: 84700836317 Rollup merge of #123807 - joboet:sys_common_thread, r=jhpratt REVERT: 504503f8b33 Stabilize (const_)slice_ptr_len and (const_)slice_ptr_is_empty_nonnull REVERT: 9d15f69e3aa Add `unsafe` to two functions with safety invariants REVERT: 587e00a6dc8 zkvm: remove cmath REVERT: 4eaade240e7 std::net: TcpListener shrinks the backlog argument to 32 for Haiku. REVERT: 3f6c217bd29 Rollup merge of #123852 - kamaboko123:fix_typo_in_std_lib_rs, r=lqd REVERT: 4b86af9b1eb Rollup merge of #123833 - dpaoliello:stdarch, r=Amanieu REVERT: d2a60a7f480 Rollup merge of #123825 - saethlin:report-nounwind-panics, r=petrochenkov REVERT: 588cc02933c Auto merge of #123846 - matthiaskrgr:rollup-85y28av, r=matthiaskrgr REVERT: 2fea2cdba1f Update document for std::io::Error::downcast REVERT: 9c18712a859 fix typo in library/std/src/lib.rs REVERT: e6af2ad4dc7 Rollup merge of #123842 - ShockYoungCHN:master, r=scottmcm REVERT: 5ae3a55f952 Rollup merge of #123830 - tgross35:f16-f128-from-inference-fix, r=Nilstrieb REVERT: 60b12568535 Auto merge of #123783 - tgross35:f16-f128-debug-impl, r=Amanieu REVERT: 973fc512315 core: get rid of `USIZE_MARKER` REVERT: f804284c2b6 Avoid panicking branch in `append_to_string` REVERT: 3089f51c1bd `VecDeque::read_to_string`: avoid making the slices contiguous REVERT: b015b3251fc Improve several `Read` implementations REVERT: df15a2a4848 Auto merge of #123490 - niluxv:strict_prov_unwind_seh, r=Amanieu REVERT: b7771f8b2ac fix pin.rs typo REVERT: ebe1b73420a Rollup merge of #123826 - kornelski:one-in-a-quintillion, r=Amanieu REVERT: 0e7d31535ea Auto merge of #120092 - zetanumbers:pin_in_static_allocator, r=Amanieu REVERT: ad02b597a23 Update stdarch submodule REVERT: 5a085ee65ac Remove `From` impls for unstable types that break inference REVERT: 476c07d5b2b Auto merge of #123823 - matthiaskrgr:rollup-8zdtggx, r=matthiaskrgr REVERT: 584cfabd699 Call the panic hook for non-unwind panics in proc-macros REVERT: 57b82a1de29 Move rare overflow error to a cold function REVERT: e4cc7157b87 Rollup merge of #123806 - joboet:advanced_overflow, r=Amanieu REVERT: f8b5999caea Rollup merge of #123798 - tniessen:patch-1, r=workingjubilee REVERT: 3bb7b59fa72 Rollup merge of #122882 - Zoxc:panic-output-panic, r=Amanieu REVERT: 721c0565871 Auto merge of #123814 - matthiaskrgr:rollup-lxn0t4t, r=matthiaskrgr REVERT: 9db1089cf77 Add a `Debug` impl and some basic functions to `f16` and `f128` REVERT: 59ee6acc9ce Refactor `panic_unwind/seh.rs` pointer use; x86 now conforms to strict-provenance REVERT: 3e1a0b58166 Stabilize `Seek::seek_relative` REVERT: 4486f025021 Auto merge of #123732 - a1phyr:io_error_factor, r=cuviper REVERT: 3ae78cd8a03 std: use queue-based `RwLock` on Windows 7 REVERT: 5a7a9cf9656 std: use queue-based `RwLock` on Xous REVERT: b934c75f308 std: use queue-based `RwLock` on SGX REVERT: 5159baabd27 std: remove `sys_common::thread` REVERT: 645f98611da core: panic on overflow in `BorrowedCursor` REVERT: e1a0f771178 Avoid invalid socket address in length calculation REVERT: 3e38e05a403 OpenBSD fix long socket addresses REVERT: a3543cf4e67 Factor some common `io::Error` constants REVERT: b7da755d5b1 Correct broken link in core::pin doc REVERT: 4b612346121 Rollup merge of #123756 - lukas-code:file-sync, r=jhpratt REVERT: e8df7df8695 Rollup merge of #123661 - tgross35:stabilize-cstr_count_bytes, r=dtolnay REVERT: f9483eaef8d Rollup merge of #123360 - adamgemmell:dev/adagem01/restricted-std, r=ehuss REVERT: 0f8750d008f Rollup merge of #122470 - tgross35:f16-f128-step4-libs-min, r=Amanieu REVERT: 72320443c24 clean up docs for `File::sync_*` REVERT: 88e034579ac Add primitive documentation for `f16` and `f128` REVERT: 17fd64487f8 Add basic f16 and f128 modules REVERT: 72ada931244 Add basic library support for `f16` and `f128` REVERT: e153272bc8d Revert "Put basic impls for f16 and f128 behind cfg(not(bootstrap))" REVERT: f756686892a Auto merge of #123725 - GuillaumeGomez:rollup-gk2bbrg, r=GuillaumeGomez REVERT: 9cb12b1ba8c Rollup merge of #123534 - ChrisDenton:name, r=workingjubilee REVERT: 4a3664831b6 visionOS: Fix unused import warning REVERT: 0e6a2681b82 Rework Path::ancestors documentation to remove unwraps REVERT: f309ec40a85 Auto merge of #122393 - a1phyr:specialize_read_buf_exact, r=joboet REVERT: 38dbe578257 Bring documentation of Path::to_path_buf in line with the rest of Path/PathBuf REVERT: ffdd870f709 Auto merge of #122812 - dtolnay:mode, r=workingjubilee REVERT: 1c86e9a0b24 Update documentation related to the recent cmd.exe fix REVERT: 390c15ab9e8 Rollup merge of #123633 - bjorn3:unsupported_command_data, r=jhpratt REVERT: 32d0cd7bbd2 Show mode_t as octal in std::fs Debug impls REVERT: 78ff007512a Add comment on UTF-16 surrogates REVERT: d3716a5bf26 Windows: set main thread name without reencoding REVERT: 3f90d4a49c3 Add const UTF-8 to UTF-16 conversion macros REVERT: f0a8f5992c3 Auto merge of #123683 - pietroalbini:pa-cve-2024-24576-nightly, r=pietroalbini REVERT: 9968366faf4 Auto merge of #123485 - madsmtm:use-libc-copyfile, r=joboet REVERT: cb50d664185 Fix dead code warning REVERT: ecda94da65a Rollup merge of #123665 - Jules-Bertholet:patch-1, r=lqd REVERT: 9618feb15f6 Rollup merge of #123254 - stepancheg:thin-box-0-const-alloc, r=oli-obk REVERT: 3e93dcf61fd Fix typo in `Future::poll()` docs REVERT: b5b840ecad8 Stabilize `cstr_count_bytes` REVERT: d1f3afbcfbf Document Windows argument splitting REVERT: a85d8fbb00b Disallow or quote all specials in bat args REVERT: 546a08e07a4 Change method calls to using the method directly REVERT: 85d08249eb6 Add `SAFETY` comments to the thread local implementation REVERT: 193fd0785f6 Update thread local docs with idiomatic cell type use REVERT: 3e9e417bf06 Rollup merge of #123564 - scottmcm:step-by-div-zero, r=joboet REVERT: ca69d3b9664 Auto merge of #120131 - oli-obk:pattern_types_syntax, r=compiler-errors REVERT: 8586a2477df Store all args in the unsupported Command implementation REVERT: 322d51c6b11 Rollup merge of #123595 - balaganesh102004:master, r=joboet REVERT: 46ff2baf0e8 Rollup merge of #123089 - Philippe-Cholet:vecdeque_pop_assume_cap, r=Nilstrieb REVERT: 40fb3529438 Rollup merge of #115984 - hermit-os:fuse, r=m-ou-se REVERT: 77ffffa2475 Add pattern types to parser REVERT: 7fc440d5712 std: update abort message in `thread::set_current` REVERT: c40d63b5b18 Add invariant to VecDeque::pop_* that len < cap if pop successful REVERT: 0eefa942d27 Auto merge of #123506 - RalfJung:miri-test-libstd, r=Mark-Simulacrum REVERT: 587f7c3ccab Auto merge of #123597 - Gbd199:patch-1, r=jhpratt REVERT: f2f504e1ed0 Fix typo in library/core/src/iter/traits/iterator.rs REVERT: 66db9e349d4 Made changes in documentation REVERT: a7d8284ffcb Auto merge of #123592 - matthiaskrgr:rollup-3k1pq8s, r=matthiaskrgr REVERT: 5940c0f0e30 Auto merge of #123561 - saethlin:str-unchecked-sub-index, r=scottmcm REVERT: 51d06bc7b22 sys_common::thread_local_key: make a note that this is not used on Windows REVERT: bbac74560fd make a doctest less slow in Miri REVERT: 3403cab01ad also test parts of std REVERT: 7bed73e68a0 disable benches in Miri REVERT: e51b7f0d11c Rollup merge of #123522 - dtolnay:constatomicintoinner, r=Nilstrieb REVERT: dbeb4549cc5 Rollup merge of #123411 - saethlin:ub-checks, r=Urgau,RalfJung REVERT: 06f6271ddc8 Rollup merge of #119224 - Duckilicious:test_main_memory_leak, r=cuviper REVERT: 766b197fe01 Don't emit divide-by-zero panic paths in `StepBy::len` REVERT: cc2f0a0b90e Use unchecked_sub in str indexing REVERT: 113e4e53d0d Drop panic hook after running tests REVERT: de9c939acda Rollup merge of #123541 - RalfJung:remove-old-hacks, r=Mark-Simulacrum REVERT: 34834b4a53e Put checks that detect UB under their own flag below debug_assertions REVERT: 738544752b1 Rollup merge of #122291 - lilasta:stabilize_const_location_fields, r=dtolnay REVERT: e6d7439b2be Rollup merge of #114788 - tisonkun:get_mut_or_init, r=dtolnay REVERT: 7ed8c46403a remove miri-test-libstd hacks that are no longer needed REVERT: 2758dcc4d06 Rollup merge of #123528 - dtolnay:asyncgeninternals, r=compiler-errors REVERT: f51e34cb326 Hide async_gen_internals from standard library documentation REVERT: 5b6d1ccbe36 Auto merge of #123433 - GnomedDev:remove-threadname-alloc, r=joboet REVERT: abd6e09dafa Stabilize const Atomic*::into_inner REVERT: 5180b60f529 Rollup merge of #123505 - ChrisDenton:revert-121666, r=workingjubilee REVERT: 63033e77821 Rollup merge of #121419 - agg23:xrOS-pr, r=davidtwco REVERT: 4963cb80557 Do not allocate for ZST ThinBox attempt 2 (using const_allocate) REVERT: b1080b2e290 Auto merge of #123317 - RalfJung:test-in-miri, r=m-ou-se,saethlin,onur-ozkan REVERT: 2f47b32cea1 Revert #121666 REVERT: 854efdee0da macOS: Use `libc` definitions for copyfile REVERT: 0200bb5d6a1 Rollup merge of #123206 - stepancheg:pointee-metadata-freeze, r=Amanieu REVERT: 4e485f71a26 Remove rt::init allocation for thread name REVERT: 6a96e4cc8be Impl `DerefPure` for more std types REVERT: a447b4e70f1 Rollup merge of #123431 - slanterns:literal_byte_character_c_string_stabilize, r=dtolnay REVERT: 3376f7ff605 Rollup merge of #123389 - ChrisDenton:dont-panic-on-startup, r=joboet REVERT: 46efe037ca8 Add comments about using debug_assert REVERT: f46c50173be force exhaustion in iter::ArrayChunks::into_remainder REVERT: 415b95a272e Rollup merge of #122356 - devnexen:dfbsd_build_fix, r=jhpratt REVERT: 9731fdd8b9e Stabilize `Literal::c_string` REVERT: 1cbda637aa2 Stabilize `Literal::byte_character` REVERT: 0741fde021e Rollup merge of #122964 - joboet:pointer_expose, r=Amanieu REVERT: de6296dd8bf add 'x.py miri', and make it work for 'library/{core,alloc,std}' REVERT: 457ae7e43bb Add docs for `FromIterator<(AE, BE)> for (A, B)` REVERT: 769ce0f1123 Implement `FromIterator<(AE, BE)>` for `(impl Default+Extend, impl Default+Extend)` REVERT: 8c4df2f59f8 rename `expose_addr` to `expose_provenance` REVERT: 8486ade2668 std: add comment about abort motivation REVERT: 11c572a0ffc Auto merge of #123390 - tgross35:f16-f128-libs-basic-impls-bootstrap, r=jhpratt REVERT: 3586bdc4067 Rollup merge of #123388 - tshepang:consistency, r=jhpratt REVERT: f7c7c7c6c00 Rollup merge of #122411 - alexcrichton:wasm32-wasip2-cabi-realloc, r=m-ou-se REVERT: 4e8d1299809 Rollup merge of #123203 - jkarneges:context-ext, r=Amanieu REVERT: 3eaf7659f60 Rollup merge of #122935 - RalfJung:with-exposed-provenance, r=Amanieu REVERT: 38cb21b0dd8 set tracking issue REVERT: 15795eeccd0 Auto merge of #123385 - matthiaskrgr:rollup-v69vjbn, r=matthiaskrgr REVERT: d9e1cac6a72 Put basic impls for f16 and f128 behind cfg(not(bootstrap)) REVERT: 39edbca03a4 Avoid panicking unnecessarily on startup REVERT: 71fefd9cf72 use a consistent style for links REVERT: 4dd5c267874 Rollup merge of #123226 - scottmcm:u32-shifts, r=WaffleLapkin REVERT: 49e00d775be Rollup merge of #123198 - krtab:build_hasher_default_const_new, r=Amanieu REVERT: c1824d1760a Auto merge of #118310 - scottmcm:three-way-compare, r=davidtwco REVERT: 08f761fb838 DOC: Add FFI example for slice::from_raw_parts() REVERT: 7b4580775aa Document restricted_std REVERT: 49c559d07e4 std: reduce code size of `set_current` REVERT: 697f9ec1a06 style: fmt REVERT: c3a76d51e31 fix: build on haiku by adding missing import REVERT: 9f0af96d7dd Auto merge of #122945 - andy-k:sorted-vec-example, r=jhpratt REVERT: 5dc90794c34 Rollup merge of #123323 - devnexen:thread_set_name_solaris_fix, r=workingjubilee REVERT: eb67e0d19d9 std::thread: set_name change for solaris/illumos. REVERT: 248dae8e519 Auto merge of #123315 - devnexen:thread_get_name_solaris, r=ChrisDenton REVERT: a5ac952e9d2 Auto merge of #123265 - joboet:guardians_of_the_unix, r=ChrisDenton REVERT: 33d26377406 update comment REVERT: 07d6bde0fed std::thread: adding get_name implementation for solaris/illumos. REVERT: 979c3657e75 Fix error message for `env!` when env var is not valid Unicode REVERT: 29c7487f353 Auto merge of #123270 - JaniM:janim/string-alloc-doc, r=workingjubilee REVERT: 0d1b4618249 doc: mention heap allocation earlier in String docs REVERT: a14153d85bf Auto merge of #123299 - workingjubilee:rollup-2z8amaj, r=workingjubilee REVERT: 89219c1acb4 Rollup merge of #123271 - JaniM:janim/sliceindex-doc, r=Nilstrieb REVERT: 6bffcfd95b4 Rollup merge of #123268 - RalfJung:dont-freeze, r=Nilstrieb REVERT: e9a72a6a9be warn against implementing Freeze REVERT: c9197ed1bbe std::thread: adding get_name haiku implementation. REVERT: 0920de9dd4c doc: describe panic conditions for SliceIndex implementations REVERT: 638a6a800d6 catch_panic: warn about panicking payload drop REVERT: 2b790b47905 std: move `thread::current` TLS variable out of `thread_info` REVERT: 72141b19dfc std: move UNIX stack overflow guard page handling into `stack_overflow.rs` REVERT: e08d065fa19 Auto merge of #123233 - devnexen:thread_get_name_bsd, r=joboet REVERT: ae3a200f9e4 Require Pointee::Metadata to be Freeze REVERT: 87c46030544 Auto merge of #123181 - stepancheg:pointee-metadata-debug, r=the8472,Amanieu REVERT: 5e0f25d32f6 Auto merge of #123085 - tgross35:f16-f128-step4.0-libs-basic-impls, r=Amanieu REVERT: 93869554cb6 Auto merge of #99322 - GKFX:const-int-parse, r=Mark-Simulacrum REVERT: d9e6e56d887 std::thread: adding freebsd/netbsd to the linux's get_name implementation. REVERT: 4df64828416 Rollup merge of #123201 - Wilfred:patch-2, r=Nilstrieb REVERT: 2f2e9839c6a Make {integer}::from_str_radix constant REVERT: 0485d6a6be9 De-LLVM the unchecked shifts [MCP#693] REVERT: a46e82446f7 Auto merge of #121948 - Gankra:stab-align, r=dtolnay REVERT: bd43b555835 Auto merge of #122976 - caibear:optimize_reserve_for_push, r=cuviper REVERT: e32adcd64a2 stabilize ptr.is_aligned, move ptr.is_aligned_to to a new feature gate REVERT: 0421b4adfe3 Auto merge of #122520 - scottmcm:stabilize_unchecked_math_basics, r=jhpratt REVERT: 1a8eb39cbb1 rustfmt REVERT: f732282ad1f Auto merge of #121268 - Urgau:improve_ambi_wide_ptr_cmps, r=Nadrieril REVERT: f01260015ea Add `Context::ext` REVERT: 8c225c06c24 Improve wording in std::any explanation REVERT: 0a72d121f0c Add fn const BuildHasherDefault::new REVERT: 1721d80e6e4 Add detection of [Partial]Ord methods to the ambiguous wide ptr cmp lint REVERT: 834687c40a5 Add diagnostic items for Ord and PartialOrd methods REVERT: c7dbd2750cd Auto merge of #122616 - Jules-Bertholet:casemappingiter-layout, r=Nilstrieb REVERT: 060fa678c2f Require Debug for Pointee::Metadata REVERT: e9af8b05c9a Auto merge of #122975 - DianQK:simplify_ub_check, r=saethlin REVERT: f1695e54eaa Auto merge of #122671 - Mark-Simulacrum:const-panic-msg, r=Nilstrieb REVERT: aee40df0050 Rename reserve_for_push to grow_one and fix comment. REVERT: 10fa6ea3565 Fix previous. REVERT: 96cbf807c24 Remove len argument from RawVec::reserve_for_push because it's always equal to capacity. Also make Vec::insert use reserve_for_push. REVERT: 6a62aeb7465 Add basic trait impls for `f16` and `f128` REVERT: 8145779f8a2 Rollup merge of #123164 - Marcondiro:unicode15-1, r=Manishearth REVERT: 6e3f1b79e3a Bump Unicode printables to version 15.1, align to unicode_data REVERT: 68bbf064838 Rollup merge of #123139 - scottmcm:simpler-nonzero-get, r=jhpratt REVERT: 67af00952c5 Rollup merge of #123136 - Vagelis-Prokopiou:fix/docs, r=ChrisDenton REVERT: 78561cce61f Rollup merge of #123133 - xiaoxiangxianzi:master, r=fmease REVERT: dca5842e32d Rollup merge of #121943 - joshlf:patch-11, r=scottmcm REVERT: 59d11980a63 `num::NonZero::get` can be 1 transmute instead of 3 REVERT: 2700969f641 Less generic code for Vec allocations REVERT: 927ab559750 Some wording improvement REVERT: 79d3fd45d2e chore: fix some comments REVERT: 5422044d734 Eliminate `UbCheck` for non-standard libraries REVERT: 3c6111e1175 Auto merge of #123128 - GuillaumeGomez:rollup-3l3zu6s, r=GuillaumeGomez REVERT: 66911604656 Rollup merge of #123083 - klensy:clippy-me, r=workingjubilee REVERT: 5c2b09604d7 impl get_mut_or_init and get_mut_or_try_init for OnceCell and OnceLock REVERT: 7114443cf67 Auto merge of #116016 - jhpratt:kill-rustc-serialize, r=ehuss REVERT: 78f45f37b51 Rollup merge of #123118 - tgross35:rwlock-docs, r=workingjubilee REVERT: a8de319911a Rollup merge of #123107 - avandesa:vec_pop_if, r=joboet REVERT: 064e82268d7 Rollup merge of #123084 - a1phyr:unixstream_read_buf, r=workingjubilee REVERT: 3e10c57aa65 Rollup merge of #123038 - he32:netbsd-ilp32-fix, r=workingjubilee REVERT: 68bb0c30f28 Rollup merge of #122880 - a1phyr:preadv_more_platform, r=workingjubilee REVERT: c876c6525dd Update `RwLock` deadlock example to not use shadowing REVERT: e34fa149934 Implement `Vec::pop_if` REVERT: e34c7e541c5 Rollup merge of #123057 - sthibaul:systemtime, r=jhpratt REVERT: dad57648f3d Rollup merge of #122835 - compiler-errors:deref-pure, r=Nadrieril REVERT: 5c7c3184650 Rollup merge of #123086 - ding-young:fix-ref-to-BufWriter, r=the8472 REVERT: a5b01cbae73 unix fs: Make hurd and horizon using explicit new rather than From REVERT: d8f1379abc3 Auto merge of #122939 - joboet:proc_macro_bridge_state, r=petrochenkov REVERT: f406df2bb28 Unix: Support more platforms with `preadv` and `pwritev` REVERT: 491d87104fc `UnixStream`: override `read_buf` REVERT: ce33622010d Fix link to BufWriter REVERT: edfdbe23dd7 std library unix/thread.rs: fix NetBSD code for ILP32 CPUs. REVERT: e7e3e1b9d0a panic_str only exists for the migration to 2021 panic macros REVERT: b626fd5085c Extract helper, fix comment on DerefPure REVERT: 4185df282bc Require DerefPure for patterns REVERT: af786093e00 Rollup merge of #123042 - dpaoliello:prelude, r=Nilstrieb REVERT: 1bdf4ecb4c5 Rollup merge of #122896 - dpaoliello:stdarch, r=Amanieu REVERT: 25260fa10d4 Rollup merge of #122707 - reedwoodruff:string_docs_typo, r=workingjubilee REVERT: 0e62a1aa862 lib: fix some unnecessary_cast clippy lint REVERT: 24376b2aa43 Import the 2021 prelude in the core crate REVERT: 78f0dbb1adc alloc::Layout: explicitly document size invariant on the type level REVERT: 7b75def6138 Rollup merge of #122990 - SkiFire13:transmute-may-copy, r=jhpratt REVERT: 6bbd18a41c7 Address PR feedback REVERT: f90e0a998d3 Amended wording REVERT: 2f023449c40 Slightly simplify the `iN::partial_cmp` MIR REVERT: 9e8ceea5e9d Rollup merge of #122992 - devnexen:available_parallelism_sol_upd, r=Amanieu REVERT: 5287647bfc6 Rollup merge of #122984 - RalfJung:panic-in-hook, r=Amanieu REVERT: 1888f00cc1f Rollup merge of #122983 - taiki-e:bsd, r=workingjubilee REVERT: 31e4f2868df Rollup merge of #122977 - cuviper:as_statically_known_str, r=RalfJung REVERT: 05ae283da3b fix build. REVERT: 0b32d628b97 std::thread: refine available_parallelism for solaris/illumos. REVERT: e954f8c7e48 Clarify transmute example REVERT: 7f0a4b6ae8b panic-in-panic-hook: formatting a message that's just a string is risk-free REVERT: e25599af462 Fix build failure on ARM/AArch64/PowerPC/RISC-V FreeBSD/NetBSD REVERT: a64212d610c Add+Use `mir::BinOp::Cmp` REVERT: 0d29868fd91 Rollup merge of #122797 - alexcrichton:fix-compile-wasm64, r=Mark-Simulacrum REVERT: 78b1cea41b1 Rollup merge of #122762 - RoboSchmied:RoboSchmied-typo, r=workingjubilee REVERT: 6c5a3d53336 Rollup merge of #120419 - Ayush1325:uefi-sys-os, r=nicholasbishop,workingjubilee REVERT: 36e2b555a98 Rename `Arguments::as_const_str` to `as_statically_known_str` REVERT: beee5246d44 Auto merge of #122966 - matthiaskrgr:rollup-20k8nsm, r=matthiaskrgr REVERT: 31e93b3a6f4 clarify equivalency of binary_search and partition_point REVERT: 8ba3c19ef23 Rollup merge of #122963 - RalfJung:core-panicking, r=m-ou-se REVERT: 2dac79d27c3 Rollup merge of #122379 - RalfJung:int2ptr-transmute, r=m-ou-se REVERT: 5e5f3084b5e Auto merge of #122905 - dpaoliello:sync-portable-simd-2024-03-22, r=workingjubilee REVERT: 342da6700ac Fixed builds with modified libc REVERT: 3eda213e527 also rename the SIMD intrinsic REVERT: 895d1b89e72 Auto merge of #122629 - RalfJung:assert-unsafe-precondition, r=saethlin REVERT: 6a618a18004 core/panicking: fix outdated comment REVERT: e938deaf0f1 try adding a test that LowerHex and friends don't panic, but it doesn't work REVERT: 3263ad86c5c refactor check_{lang,library}_ub: use a single intrinsic, put policy into library REVERT: c629e7a93f8 move assert_unsafe_preconditions to its own file REVERT: 5d48a0357a6 Auto merge of #122947 - matthiaskrgr:rollup-10j7orh, r=matthiaskrgr REVERT: f44d047f888 Rollup merge of #122931 - herobs:patch-1, r=joboet REVERT: 0d1cab9d2b5 Rollup merge of #122930 - RalfJung:panic-in-panic-fmt, r=Amanieu REVERT: 953c42c2d58 Rollup merge of #122916 - MultisampledNight:docs-sync-typo, r=jhpratt REVERT: 7d5b8a25657 Rollup merge of #120577 - wutchzone:slice_split_at_unchecked, r=m-ou-se REVERT: 41ccb132f38 Auto merge of #122582 - scottmcm:swap-intrinsic-v2, r=oli-obk REVERT: 2704e90a581 improve example on inserting to a sorted vector to avoid shifting equal elements REVERT: 16022f9265f rename ptr::from_exposed_addr -> ptr::with_exposed_provenance REVERT: 6dbc32b295b proc_macro: simplify bridge state REVERT: a9d12dd1a9f Fix some typos in the pin.rs REVERT: f3dcd4a742d add panic location to 'panicked while processing panic' REVERT: 1c643468730 Auto merge of #119552 - krtab:dead_code_priv_mod_pub_field, r=cjgillot,saethlin REVERT: 3b67ff0cb3e Merge commit 'cff979eec1ac0473fc4960ee6cde462c6aeda824' into sync-portable-simd-2024-03-22 REVERT: 443c645f4b3 docs(sync): normalize dot in fn summaries REVERT: fc539821467 Remove RustcEncodable/Decodable from 2024 prelude REVERT: ca0e3c3ae1a Soft-destabilize `RustcEncodable`/`RustcDecodable` REVERT: 953ea0a1e58 Update stdarch submodule REVERT: 0f7c3b3e7d6 `swap_simple` no longer needs to be a separate function REVERT: 50d95d93b0c Avoid a panic in `set_output_capture` in the default panic handler REVERT: 280bc7d82ad Codegen const panic messages as function calls REVERT: 241ba61f377 Rollup merge of #122800 - zachs18:nonnull-slice-is_empty, r=Amanieu REVERT: 5951b094c2e Auto merge of #122024 - clubby789:remove-spec-option-pe, r=jhpratt REVERT: 22221dbd7eb Rollup merge of #122829 - ShoyuVanilla:gen-block-impl-fused-iter, r=compiler-errors REVERT: 571bfda2b71 Rollup merge of #122817 - ultrabear:ultrabear_btreedoc, r=Nilstrieb REVERT: 132e16f4845 Rollup merge of #121881 - devnexen:bsd_acceptfilter, r=Amanieu REVERT: 27602fcc7db Not insta-stable REVERT: 94a08264b99 Auto merge of #122785 - the8472:const-select-specialized-impl, r=Amanieu REVERT: 1d8ba1b31b2 Implement `FusedIterator` for `gen` block REVERT: ed109e1fff2 Implement macro-based deref!() syntax for deref patterns REVERT: 8fcb41ef166 Stabilize `const_caller_location` and `const_location_fields` REVERT: 88ef094e9fe Rollup merge of #122806 - compiler-errors:type-ascribe, r=fmease REVERT: 03a162c1261 document into_iter in top level docs iterator ordering guarantees REVERT: add175b3da4 document iteration ordering on into_iter method instead of IntoIterator implementation REVERT: 2c758f0ae42 BTree(Set|Map): Guarantee that `IntoIter` will iterate in sorted by key order REVERT: 21485563d80 Make type_ascribe! not a built-in REVERT: d8fbe999932 Rollup merge of #122765 - workingjubilee:test-for-vec-handling-usize-max, r=Nilstrieb REVERT: 9e601f1b8b3 Rollup merge of #122729 - m-ou-se:relax, r=Amanieu REVERT: d9e295f1ab4 Add `NonNull::<[T]>::is_empty` as insta-stable. REVERT: cccb5088d79 Fix compile of wasm64-unknown-unknown target REVERT: 2c474d83a04 Auto merge of #122761 - jwong101:fix/vec-insert, r=workingjubilee,Nilstrieb REVERT: 3d4d0641c3e select Vec::from_iter impls in a const block to optimize compile times REVERT: a2ed0d196d4 std::net: adding acceptfilter feature for netbsd/freebsd. REVERT: 8e9f027dbe7 Update target.rs alloc.rs event.rs simd.rs REVERT: a443b96c9d7 SeqCst->Relaxed in condvar test. REVERT: d261e3cee8a SeqCst->Relaxed in thread local test. REVERT: 514fd74ab40 SeqCst->Relaxed in std::net::test. REVERT: 2e96b9bfb7a Use less restricted memory ordering in xous::thread_local_key. REVERT: dd7927a2d29 Auto merge of #122754 - Mark-Simulacrum:bootstrap-bump, r=albertlarsan68 REVERT: 62fb165c1b8 step cfgs REVERT: f8ec29cd69f Auto merge of #120717 - compiler-errors:cap-closure-kind, r=oli-obk REVERT: c6d2bb7445c improve codegen of fmt_num to delete unreachable panic REVERT: 6d8be786ce3 Add usize::MAX arg tests for Vec REVERT: db8c896be2f Rollup merge of #122739 - Sky9x:insert-put, r=jhpratt REVERT: 6adcb2c7add Rollup merge of #122730 - ferrocene:hoverbear/qnx-ucred-cfgs, r=Amanieu REVERT: ac8de22c9f0 Rollup merge of #121543 - onur-ozkan:clippy-args, r=oli-obk REVERT: 16e3fdef4ae fix OOB pointer formed in Vec::index REVERT: 5fefabbe6d2 branch 1.78: replace-version-placeholder REVERT: 0bdf2a8ac26 resolve clippy errors REVERT: 96d7f0c54db Only split by-ref/by-move futures for async closures REVERT: b31660cd246 Add "put" as a confusable for insert on hash map/set REVERT: 66b9f792315 Rollup merge of #122720 - heisen-li:offset_of, r=workingjubilee REVERT: 109470d3d8d Manually implement `PartialOrd`/`Ord` for `Option` REVERT: 82edda8ed6c Remove `SpecOptionPartialEq` REVERT: 1e803f2dc70 Expose ucred::peer_cred on QNX targets to enable dist builds REVERT: 2b29c96699d SeqCst->Relaxed for xous set_nonblocking. REVERT: f88a7963c55 SeqCst->{Release,Acquire} for xous DropLock. REVERT: 9abd38f174a SeqCst->Relaxed in pal::windows::pipe. REVERT: 9820ffeccef SeqCst->{Release,Acquire} for wasm DropLock. REVERT: f2380b3b3e1 SeqCst->{Release,Acquire} in sys_common::thread_local_key. REVERT: b5d0406a05c Use less restricted memory ordering in thread_parking::pthread. REVERT: 885af3702ad SeqCst->{Release,Acquire} in xous mutex. REVERT: ef4e684a7f7 SeqCst->Relaxed for FIRST_PANIC. REVERT: 21eb9e2ee01 SeqCst->{Release,Acquire} for alloc error hook. REVERT: 3e7a35ef902 SeqCst->Relaxed for proc_macro bridge counter. REVERT: bc52b591580 SeqCst->Relaxed in panic_unwind/emcc. REVERT: 4c7e127f4ea SeqCst->Relaxed in doc examples. REVERT: df612829d85 [doc]:fix error code example REVERT: c695d1bf63d Make ptr_guaranteed_cmp a rustc_intrinsic and favor its body over backends implementing it REVERT: e2f11bcf3c0 Make `vtable_align` a rustc_intrinsic REVERT: 1eb203d957b Make `const_eval_select` a rustc_intrinsic REVERT: ac3846bcacf add notes on how to store 'ptr or int' REVERT: 3db94e8645b Support for visionOS REVERT: ac5ae5d5990 Reimplement `CaseMappingIter` with `core::array::IntoIter` REVERT: b6679c0558e Auto merge of #122055 - compiler-errors:stabilize-atb, r=oli-obk REVERT: 68f41577d69 Rollup merge of #122675 - tmfink:doc-clarify, r=scottmcm REVERT: 638f0a8bb85 Rollup merge of #122642 - pallix:improve-wording-for-vec-swap_remove, r=Amanieu REVERT: ef35b91b783 Fix a typo in the alloc::string::String docs REVERT: 5091bd7760f remove retag_box_to_raw, it is no longer needed REVERT: 4650a14f02a add_retag: ensure box-to-raw-ptr casts are preserved for Miri REVERT: 698c6d9c530 Let codegen decide when to `mem::swap` with immediates REVERT: 1d3d348859f Improve wording of `Vec::swap_remove` REVERT: d03788e007b chore(121952): echo comments on the `*_assign` methods REVERT: 4a4b268f69d chore(121952): remove redundant comments REVERT: d7a48470e99 feat: implement `{Div,Rem}Assign>` on `X` REVERT: 8e0f8666369 Rollup merge of #119411 - yotamofek:array-ptr-get, r=Nilstrieb REVERT: 99363a1d9f2 core: document default attribute stabilization REVERT: c4ae972a056 Optimize `core::char::CaseMappingIter` layout REVERT: 4c7bb8d5f0d Auto merge of #121885 - reitermarkus:generic-nonzero-inner, r=oli-obk,wesleywiser REVERT: f4c6e2f8380 Rollup merge of #122601 - joboet:ptr_replace, r=workingjubilee REVERT: 056c6965e47 Add as_(mut_)ptr and as_(mut_)slice to raw array pointers REVERT: 25c29d18ea3 Rollup merge of #122583 - Zoxc:tls-non-mut, r=joboet REVERT: ad38304cf28 Rollup merge of #122390 - ChrisDenton:bindgen, r=Mark-Simulacrum REVERT: 21f66a1d693 core: optimize `ptr::replace` REVERT: 559a10436c9 Use `UnsafeCell` for fast constant thread locals REVERT: 5be79977acd Rollup merge of #122562 - Wilfred:break_keyword_docs, r=workingjubilee REVERT: 19aa96cfde2 Workaround issue 122566 REVERT: d1623e9912d Mention labelled blocks in `break` docs REVERT: a71c75e30e9 Rollup merge of #122512 - baitcode:2024-03-14-buffer-documentation-fix, r=Nilstrieb REVERT: 26b22f30d47 Stabilize `unchecked_{add,sub,mul}` REVERT: b2112250f70 Auto merge of #122511 - matthiaskrgr:rollup-swzilin, r=matthiaskrgr REVERT: 8b661702d9f Use rust-lang/backtrace-rs@6fa4b85 REVERT: ed30c0114aa Rollup merge of #122498 - jfgoog:update-cc-crate-version, r=workingjubilee REVERT: 8f043860be1 Rollup merge of #122479 - GrigorenkoPV:duration_millis_float, r=scottmcm REVERT: d7b90d860d0 Rollup merge of #121650 - GrigorenkoPV:cap_setgid, r=Amanieu REVERT: b3d55625c6e Fix minor documentation issue. Code outside the test would fail. Seek documentation clearly states that negative indexes will cause error. Just making the code in the example to return Result::Ok, instead of Result::Error. REVERT: c640d978655 Update version of cc crate REVERT: 14035d07a36 Hide implementation details for `NonZero` auto traits. REVERT: d1f5e673fe7 Rollup merge of #119029 - dylni:avoid-closing-invalid-handles, r=ChrisDenton REVERT: f92b0d91c2f Implement ptr_as_ref_unchecked (#122034) REVERT: 9338daeca7f Auto merge of #122483 - matthiaskrgr:rollup-n07dsh5, r=matthiaskrgr REVERT: 2cdbd5b05a4 Rollup merge of #122461 - the8472:fix-step-forward-unchecked, r=Amanieu REVERT: 2ae6fb6e788 Rollup merge of #122421 - CAD97:step-trait-docs, r=jhpratt REVERT: fde38c8e684 Rollup merge of #104353 - clarfonthey:cstr-bytes-iter, r=cuviper REVERT: 9ab7ca4225d Auto merge of #114038 - Stargateur:108277, r=ChrisDenton REVERT: 76efb6428b4 fix unsoundness in Step::forward_unchecked for signed integers REVERT: 11b745fbc6b Implement `Duration::as_millis_{f64,f32}` REVERT: e1d5cafe3e1 Provide `cabi_realloc` on `wasm32-wasip2` by default REVERT: 4be2029c1b2 Get wasm32-wasip2 compiling with its custom pal implementation REVERT: db8c957760e Rollup merge of #122386 - joboet:move_pal_once, r=jhpratt REVERT: 557b190f526 Rollup merge of #122255 - Nadrieril:min_exh_pats-libs, r=scottmcm REVERT: 4900722b75d Improve Step docs REVERT: d7df67f55e7 Reduce unsafe code, use more NonNull APIs per @cuviper review REVERT: dedeeb09a13 Specialize many implementations of `Read::read_buf_exact` REVERT: 354df78141b transmute: caution against int2ptr transmutation REVERT: 74989423f11 Convert [u8] to [i8] in test REVERT: 323195a7360 Bump windows-bindgen to 0.55.0 REVERT: 2f04875c49d Bump windows-bindgen to 0.54.0 REVERT: 94050f85a72 std: move `Once` implementations to `sys` REVERT: 4e4ed209c02 Fix typo in lib.rs of proc_macro REVERT: ee32b661639 Allow dead code in sys/pal REVERT: 7fe24bd817c Allow dead code in thread local dtor REVERT: 02233db5f26 Remove unused fields in some structures REVERT: b9e42937190 Use `min_exhaustive_patterns` in core & std REVERT: 8a8d19da9ce std::rand: fix dragonflybsd after #121942. REVERT: b46f839cfed Auto merge of #122036 - alexcrichton:test-wasm-with-wasi, r=oli-obk REVERT: 8e39145af44 libtest: Print timing information on WASI REVERT: ad161738d1d Rollup merge of #121438 - coolreader18:wasm32-panic-unwind, r=cuviper REVERT: 5ec2f2cfaa6 Auto merge of #122331 - jhpratt:rollup-cbl8xsy, r=jhpratt REVERT: dc5de3d4f6d Rollup merge of #122326 - Zoxc:win-alloc-tweak, r=ChrisDenton REVERT: e694713ce82 Rollup merge of #122298 - RalfJung:raw-vec-into-box, r=cuviper REVERT: 9562390bc25 Rollup merge of #122002 - devnexen:thread_stack_netbsd_fix, r=workingjubilee,riastradh REVERT: 33c34eadeb1 Rollup merge of #121840 - oli-obk:freeze, r=dtolnay REVERT: aa105513771 Rollup merge of #121633 - ChrisDenton:precise, r=Nilstrieb REVERT: 71feb9bc03d Rollup merge of #121148 - clarfonthey:try-range, r=dtolnay REVERT: 74e83551126 Auto merge of #117156 - jmillikin:os-unix-socket-ext, r=Amanieu,dtolnay REVERT: 8d989141cd1 Optimize `process_heap_alloc` REVERT: 534708e729a Auto merge of #122312 - matthiaskrgr:rollup-0p8y7gg, r=matthiaskrgr REVERT: 7efbdd34d68 Rollup merge of #122302 - ratmice:issue122234, r=cuviper REVERT: 5a0a01871c7 Rollup merge of #122277 - RalfJung:BorrowedCursor, r=cuviper REVERT: 944c6402aaf Rollup merge of #122276 - RalfJung:io-read, r=Nilstrieb REVERT: 9141a657b4e Rollup merge of #122275 - RalfJung:std-oom, r=workingjubilee REVERT: 86e9b7020c2 Add CStr::bytes iterator REVERT: 9119a88daf2 Update backtrace submodule to 0.3.70 REVERT: 2a351437c48 docs: Correct ptr/ref verbiage in SliceIndex docs. REVERT: 4e59924d77a RawVec::into_box: avoid unnecessary intermediate reference REVERT: 2c75bb56f31 Fix lint. REVERT: 69f2909f5ae Move generic `NonZero` `rustc_layout_scalar_valid_range_start` attribute to inner type. REVERT: 17eea62ffb3 Rollup merge of #122271 - pitaj:diag_items-legacy_numeric_constants, r=Nilstrieb REVERT: 162704ab5f6 Rollup merge of #122244 - tvallotton:local_waker_leak_fix, r=Nilstrieb REVERT: 4c111ae9601 Rollup merge of #121942 - devnexen:getrandom_for_dfbsd, r=joboet REVERT: b7f02800408 Rollup merge of #113525 - workingjubilee:handle-dynamic-minsigstksz, r=m-ou-se REVERT: df1d279a07e Rollup merge of #112136 - clarfonthey:ffi-c_str, r=cuviper REVERT: 0cbacab3627 BorrowedCursor docs clarification REVERT: 2786853ff7a io::Read trait: make it more clear when we are adressing implementations vs callers REVERT: 1a6ecbb621b disable OOM test in Miri REVERT: a4b58b3297b fix legacy numeric constant diag items REVERT: e53abfcc702 Auto merge of #121662 - saethlin:precondition-unification, r=RalfJung REVERT: 7e2f02fb3bf Rollup merge of #121711 - ChrisDenton:junction, r=Mark-Simulacrum REVERT: 3c283ef826d Rollup merge of #121403 - kornelski:io-oom, r=dtolnay REVERT: d1870b35d6f Rollup merge of #121280 - ajwock:maybeuninit_fill, r=Amanieu REVERT: 78ff5504850 Rollup merge of #120504 - kornelski:try_with_capacity, r=Amanieu REVERT: e4e154f005c Rollup merge of #114655 - nbdd0121:io-safety, r=dtolnay REVERT: b9564b7e64d Rollup merge of #99153 - Dajamante:issue/95622, r=dtolnay REVERT: c2819a68666 Explain why we don't use intrinsics::is_nonoverlapping REVERT: 234116791f9 fix: remove memory leak due to missing drop implementation for local waker. Also, fix some of the stability attributes of LocalWaker's methods. REVERT: 3d513599c30 NonZero::from_mut_unchecked is library UB REVERT: 8a43d9ffa52 Avoid closing invalid handles REVERT: 6694cf026d7 Improve docs REVERT: c96bcc6ea4a Rollup merge of #122233 - RalfJung:custom-alloc-box, r=oli-obk REVERT: 3742d27544a Rollup merge of #122232 - RalfJung:misc, r=jhpratt REVERT: f53243880b4 Rollup merge of #121358 - GnomedDev:lower-align-typeid, r=Mark-Simulacrum REVERT: 6cd34e99b17 miri: do not apply aliasing restrictions to Box with custom allocator REVERT: b9e8877d692 fn is_align_to: move some comments closer to the cast they refer to REVERT: bb2f536f8c9 fix warning when building libcore for Miri REVERT: 056a9991346 Auto merge of #122095 - lukas-code:windows-shutdown-test, r=ChrisDenton REVERT: 35a151585c9 Distinguish between library and lang UB in assert_unsafe_precondition REVERT: 3e295db7505 further changes from feedback REVERT: e0fca7a80a3 Stabilize associated type bounds REVERT: 54c23e64bcf Rollup merge of #121201 - RalfJung:align_offset_contract, r=cuviper REVERT: 0e014c39087 Document overrides of `clone_from()` REVERT: 7e3a3db7a2d align_offset, align_to: no longer allow implementations to spuriously fail to align REVERT: 1e24803b17b Rollup merge of #122099 - Urgau:btreemap-inline-new, r=Amanieu REVERT: db0a06ed8c1 Rollup merge of #121938 - blyxxyz:quadratic-vectored-write, r=Amanieu REVERT: 32f69cfacac Rollup merge of #120608 - kornelski:slice-ptr-doc, r=cuviper REVERT: fc3c23c7ff0 Rollup merge of #118623 - haydonryan:master, r=workingjubilee REVERT: 4e62f99c5fc Auto merge of #122059 - nyurik:with-as-const-str, r=cuviper REVERT: cc5780c21cb Rollup merge of #122147 - kadiwa4:private_impl_mods, r=workingjubilee REVERT: 574a6bf4991 Rollup merge of #119888 - weiznich:stablize_diagnostic_namespace, r=compiler-errors REVERT: 65325da7119 make `std::os::unix::ucred` module private REVERT: 4161077f383 Rust is a proper name: rust → Rust REVERT: e5ab074b006 Auto merge of #122113 - matthiaskrgr:rollup-5d1jnwi, r=matthiaskrgr REVERT: cecc9528316 Rollup merge of #122088 - ChrisDenton:fixme, r=workingjubilee REVERT: 6f45029d2d4 Rollup merge of #122072 - KonradHoeffner:patch-1, r=cuviper REVERT: c156a81d9f1 Rollup merge of #122091 - ChrisDenton:comment, r=RalfJung REVERT: 1beba1ff75b Rollup merge of #122074 - KonradHoeffner:patch-2, r=jhpratt REVERT: 05671749e6e Rollup merge of #113518 - jyn514:streaming-failures, r=cuviper REVERT: 95530d87780 Document and test minimal stack size on Windows REVERT: 7045d043274 Add #[inline] to BTreeMap::new constructor REVERT: 71b8e46e973 Dynamically size sigaltstk in std REVERT: 5ba3f952024 fix `close_read_wakes_up` test REVERT: 7a5dfd7ea25 Note why we're using a new thread in a test REVERT: a7303b9d034 Remove unnecessary fixme REVERT: 30c876cbfb4 Be stricter with `copy_file_range` probe results REVERT: 3b7d1c3b79d Auto merge of #121956 - ChrisDenton:srwlock, r=joboet REVERT: fe052461e10 Less syscalls for the `copy_file_range` probe REVERT: 0999f9ca37f add missing PartialOrd impl doc for array REVERT: 2feba531613 Refer to "slice" instead of "vector" in Ord and PartialOrd trait impl of slice REVERT: 5547994c6d8 unix time module now return result REVERT: 73614f56775 Optimize write with as_const_str for shorter code REVERT: a27191d7e08 Rollup merge of #122018 - RalfJung:box-custom-alloc, r=oli-obk REVERT: 2dcbff18228 Rollup merge of #122016 - RalfJung:will_wake, r=dtolnay REVERT: 6b690c8a1ca Rollup merge of #121894 - RalfJung:const_eval_select, r=oli-obk REVERT: 4062b5df853 Rollup merge of #121065 - CAD97:display-i18n, r=cuviper REVERT: ebe605b6281 Add `Waitable` trait REVERT: 1252cd1bdd4 Implement MaybeUninit::fill{,_with,_from} REVERT: 94f6ed4f7cf Auto merge of #121428 - okaneco:ipaddr_parse, r=cuviper REVERT: e3e1ea49a8e only set noalias on Box with the global allocator REVERT: 04b0f470549 Auto merge of #121138 - Swatinem:grapheme-extend-ascii, r=cuviper REVERT: 75950eea9bc will_wake tests fail on Miri and that is expected REVERT: eb10acd1995 Auto merge of #122012 - matthiaskrgr:rollup-bzqjj2n, r=matthiaskrgr REVERT: 74b6933fb78 Rollup merge of #121826 - estebank:e0277-root-obligation-2, r=oli-obk REVERT: dfaeba0b8fd Rollup merge of #121287 - zachs18:rc-into-raw-must-use, r=cuviper REVERT: b30787b5753 Rollup merge of #121262 - 20jasper:add-vector-time-complexity, r=cuviper REVERT: 8750e154492 Rollup merge of #121213 - Takashiidobe:takashi/example-for-rc-into-inner, r=cuviper REVERT: 6d82806d5aa Auto merge of #121001 - nyurik:optimize-core-fmt, r=cuviper REVERT: 7bd13c02f4e libtest: Print the names of failed tests eagerly REVERT: 37ab9325a34 doc wording improvements REVERT: 6cd0c832f5a Explain use of display adapters REVERT: f0ade3422bf Windows: Implement mutex using futex REVERT: 3074f38431f Auto merge of #120675 - oli-obk:intrinsics3.0, r=pnkfelix REVERT: 69feac983fe Add benches for `net` parsing REVERT: 750d9b86077 net: Add branch to Parser::read_number for parsing without checked arithmetic REVERT: 4f1d6909390 std::threads: revisit stack address calculation on netbsd. REVERT: b37daadabd1 Rollup merge of #121977 - Lee-Janggun:master, r=WaffleLapkin REVERT: 88755c2dd19 Rollup merge of #121968 - roblabla:fix-win7, r=jhpratt REVERT: 6d0bb984f0d Rollup merge of #121939 - jonaspleyer:patch-typo-core-From-descr, r=workingjubilee REVERT: b1bc3e02054 Rollup merge of #121732 - Voultapher:improve-assert_matches-documentation, r=cuviper REVERT: e2937799f4c Rollup merge of #120976 - matthiaskrgr:constify_TL_statics, r=lcnr REVERT: 8430ecb7cf8 Add a scheme for moving away from `extern "rust-intrinsic"` entirely REVERT: 35e5a9cd9c1 Fix comment in Atomic{Ptr,Bool}::as_ptr. REVERT: e5b40ab7c81 include feedback from workingjubilee REVERT: 0e324c7ea87 Don't run test_get_os_named_thread on win7 REVERT: 3e797a33e0f Rollup merge of #121935 - RalfJung:ptr-without-prov, r=scottmcm REVERT: 660ab6244e1 Be more lax in `.into_iter()` suggestion when encountering `Iterator` methods on non-`Iterator` REVERT: e2361fb075d Use root obligation on E0277 for some cases REVERT: 04e9e6ada64 Update library/core/src/sync/atomic.rs REVERT: 668172d3171 Update library/core/src/sync/atomic.rs REVERT: 0afa385a5ff Use "size and alignment" rather than layout REVERT: 1ccd5577f5e Document AtomicPtr bit validity REVERT: 06da8d4c095 Clarify bit validity for AtomicBool REVERT: b1112959f9f Clarify atomic bit validity REVERT: 089e493103d std::rand: enable getrandom for dragonflybsd too. REVERT: 1c045731790 Apply suggestions from code review REVERT: c635e33f9fb Small enhancement to description of From trait REVERT: 865604687f0 Fix quadratic behavior of repeated vectored writes REVERT: 3572d5763f3 library/ptr: mention that ptr::without_provenance is equivalent to deriving from the null ptr REVERT: 6ed2af125db Add missing get_name for wasm::thread. REVERT: 6ea387bcf42 Auto merge of #121856 - ChrisDenton:abort, r=joboet REVERT: 2619acdba77 Auto merge of #121914 - Nadrieril:rollup-ol98ncg, r=Nadrieril REVERT: f0801511b8e Rollup merge of #121622 - dtolnay:wake, r=cuviper REVERT: 68d55671c95 Cleanup windows abort_internal REVERT: d954628fec4 typo REVERT: 4a156395cf0 Rollup merge of #121888 - cppcoffee:style, r=Nilstrieb REVERT: 9b10d83a189 Rollup merge of #121759 - RalfJung:addr_of, r=the8472 REVERT: 705bca47cef Rollup merge of #121758 - joboet:move_pal_thread_local, r=ChrisDenton REVERT: 7f1dfee5e76 Rollup merge of #121666 - ChrisDenton:thread-name, r=cuviper REVERT: 2e107e02af4 const_eval_select: make it safe but be careful with what we expose on stable for now REVERT: afadf202aa2 Apply review comments REVERT: 070f0a85910 attempt to further clarify addr_of docs REVERT: ae55e080c7f Rollup merge of #121861 - tbu-:pr_floating_point_exact_examples, r=workingjubilee REVERT: 84d3acfd568 Rollup merge of #121847 - shamatar:btreemap_fix_implicits, r=cuviper REVERT: f3a9659fe5c Rollup merge of #121835 - nnethercote:mv-HandleStore, r=bjorn3 REVERT: 0b6c0acd424 Rollup merge of #109263 - squell:master, r=cuviper REVERT: cb9f2f70cf2 style library/core/src/error.rs REVERT: aaffae72706 Rollup merge of #121730 - ecnelises:aix_pgo, r=wesleywiser REVERT: e85e891f362 Rollup merge of #121634 - RavuAlHemio:slice-prefix-suffix-docs, r=cuviper REVERT: 74a1f0c8142 Add `get_name` placeholder to other targets REVERT: 62a9b9c93ef Move capacity_overflow function to make ui tests change less REVERT: b537b17fbaa try_with_capacity for Vec, VecDeque, String REVERT: 128433c24f1 try_with_capacity for RawVec REVERT: 22314a531b0 Use the guaranteed precision of a couple of float functions in docs REVERT: bebb9ea7c57 Rollup merge of #121850 - reitermarkus:generic-nonzero-unsafe-trait, r=Nilstrieb REVERT: f1871c3d442 Rollup merge of #121736 - HTGAzureX1212:HTGAzureX1212/remove-mutex-unlock, r=jhpratt REVERT: 2cb31dc4d28 Make `ZeroablePrimitive` trait unsafe. REVERT: 36fab021aed remove hidden use of Global REVERT: 1df64282b65 revise interface to read directory entries REVERT: 205418fa11f Extending filesystem support for hermit-os REVERT: a3cdf362b8b Move `HandleStore` into `server.rs`. REVERT: f49177a442d Auto merge of #114016 - krtab:delete_sys_memchr, r=workingjubilee REVERT: 68b566cdc2b Rollup merge of #121809 - tgross35:suggest-path-split-fixup, r=Amanieu REVERT: 018584b9cbd Rollup merge of #121753 - mu001999:core/add_cfg, r=cuviper REVERT: 5d651230624 Rollup merge of #121681 - jswrenn:nix-visibility-analysis, r=compiler-errors REVERT: d45670885c3 Remove doc aliases to PATH REVERT: 3d9b11435f8 Rollup merge of #121596 - ChrisDenton:tls, r=joboet REVERT: 2f57d3e6e30 Forbid implementing `Freeze` even if the trait is stabilized REVERT: de4cd3eae3c Expose `Freeze` trait again REVERT: 9d594b70e50 Rollup merge of #121793 - tbu-:pr_floating_point_32, r=Amanieu REVERT: 6f29e7a2f56 Rollup merge of #121765 - hermit-os:errno, r=ChrisDenton REVERT: 18a5bfe6631 Rollup merge of #118217 - tbu-:pr_floating_point, r=Amanieu REVERT: 2b44b9eefca Document which methods on `f32` are precise REVERT: 29557831025 Document the precision of `f64` methods REVERT: 2c2ba108e86 Rollup merge of #121778 - ibraheemdev:patch-19, r=RalfJung REVERT: c743bceef96 Rollup merge of #121768 - ecton:condvar-unwindsafe, r=m-ou-se REVERT: 51dee9fc787 Rollup merge of #120291 - pitaj:string-sliceindex, r=Amanieu REVERT: 2951919a850 Rollup merge of #119748 - tgross35:suggest-path-split, r=Amanieu REVERT: 0d73d4adaf5 Drop link to matches macro and link matches macro to assert_matches. REVERT: f1dc4ac037d fix typos REVERT: dfe1fc2d7f4 document potential memory leak in unbounded channel REVERT: d713738e3c4 Add proper cfg REVERT: f89c0681402 Rollup merge of #110543 - joboet:reentrant_lock, r=m-ou-se REVERT: bfe5ae55379 Implement unwind safety for Condvar REVERT: 0b89e67a8be add platform-specific function to get the error number for HermitOS REVERT: 3747ff34982 std: move thread local implementation to `sys` REVERT: 7897a18f033 Rollup merge of #121691 - janstarke:handle-missing-creation-time-as-unsupported, r=cuviper REVERT: fa6b1862f17 Rollup merge of #120051 - riverbl:os-str-display, r=m-ou-se REVERT: 9a830a0f1c5 remove Mutex::unlock REVERT: 0961acc0cba Improve assert_matches! documentation REVERT: 84617e5539f Add profiling support to AIX REVERT: 20c02cc556f Implement junction_point REVERT: 6db7e059b0b Auto merge of #119616 - rylev:wasm32-wasi-preview2, r=petrochenkov,m-ou-se REVERT: 2bd8808a5da handle unavailable creation time as `io::ErrorKind::Unsupported` REVERT: e8eda6e9a6a have `String` use `SliceIndex` impls from `str` REVERT: 50ad9c25508 safe transmute: revise safety analysis REVERT: 2bbb714b758 Auto merge of #119636 - devnexen:linux_tcp_defer_accept, r=m-ou-se REVERT: 59ea7dbb02c Rename wasm32-wasi-preview2 to wasm32-wasip2 REVERT: 89c39f261c7 Add the wasm32-wasi-preview2 target REVERT: 06c41fd8eea Test getting the OS thread name REVERT: 30847ccc8ff Use the OS thread name by default for the current thread REVERT: e384a41925d intrinsics.rs: add some notes on unwinding REVERT: 01b9b83c8e0 Stabilize the `#[diagnostic]` namespace and `#[diagnostic::on_unimplemented]` attribute REVERT: 72f6010e45a Generate original vtable and clone's vtable in the same CGU REVERT: 823d14f92d7 Auto merge of #121655 - matthiaskrgr:rollup-qpx3kks, r=matthiaskrgr REVERT: ed4bb097a2c Rollup merge of #121648 - jieyouxu:from-into-raw-parts-docs, r=Nilstrieb REVERT: 50b156d4655 Rollup merge of #121598 - RalfJung:catch_unwind, r=oli-obk REVERT: ebf67e2a092 Auto merge of #121516 - RalfJung:platform-intrinsics-begone, r=oli-obk REVERT: a2cc79ab4cf change std::process to drop supplementary groups based on CAP_SETGID REVERT: deb2e443441 Document args returned from `String::into_raw_parts` REVERT: d3b08ce8101 Document args returned from `Vec::into_raw_parts{,_with_alloc}` REVERT: ac1fe4cb848 Rearrange `String::from_raw_parts` doc argument order to match code argument order REVERT: 0fa995daad1 Rearrange `Vec::from_raw_parts{,_in}` doc argument order to match code argument order REVERT: cd1df70afce fix race between block initialization and receiver disconnection REVERT: ea89df1720e Don't codegen wasm.throw unless with -Zbuild-std REVERT: e53e2d36b0b Remove _tls_used trickery unless needed REVERT: e03dceb3a9d Clarify behavior of slice prefix/suffix operations in case of equality REVERT: a8c3b12ecb4 Use volatile to make `p_thread_callback` used REVERT: e97d0a803f4 Win10: Use GetSystemTimePreciseAsFileTime directly REVERT: 6f4e8f7096d miri: rename miri_start_panic → miri_start_unwind REVERT: 4e9cd3840b8 rename 'try' intrinsic to 'catch_unwind' REVERT: b89280a0f6e Fill in Read::read_buf for &Stdin REVERT: fa28504548c Fix stable feature name and stabilization version of Read for &Stdin REVERT: 415c9b5d6b7 Auto merge of #121317 - ChrisDenton:win10-sync, r=Mark-Simulacrum REVERT: d9878e45f33 Add Waker::will_wake tests REVERT: 4c779365387 Auto merge of #120393 - Urgau:rfc3373-non-local-defs, r=WaffleLapkin REVERT: e7d49dc1fad Auto merge of #121591 - matthiaskrgr:rollup-8wfhh3v, r=matthiaskrgr REVERT: aae4f43b8fd Rollup merge of #121513 - nshyrei:fix_tests_module, r=cuviper REVERT: d18bc841336 Rollup merge of #119590 - ChrisDenton:cfg-target-abi, r=Nilstrieb REVERT: cebe0017b1f Fix Hash impl REVERT: c7d8eb0c206 Windows: Use ProcessPrng for random keys REVERT: 469292b669d Make push docs more vague REVERT: 85769226c6b remove platform-intrinsics ABI; make SIMD intrinsics be regular intrinsics REVERT: 93527c0da50 Auto merge of #117107 - zachs18:mapped-mutex-guard, r=Amanieu REVERT: cb645d493f2 Auto merge of #121114 - Nilstrieb:no-inline!, r=saethlin REVERT: df6c1975f77 Auto merge of #121569 - matthiaskrgr:rollup-awglrax, r=matthiaskrgr REVERT: ae9a8557c45 Rollup merge of #121556 - GrigorenkoPV:addr_of, r=Nilstrieb REVERT: 95a17b8bb55 Rollup merge of #121551 - nbdd0121:ffi_unwind, r=RalfJung REVERT: e6563106f22 Rollup merge of #121530 - wgslr:master, r=Mark-Simulacrum REVERT: 8578c1e7750 Rollup merge of #121343 - Takashiidobe:takashi/examples-for-slice, r=Mark-Simulacrum REVERT: f32ddaeacda Stabilize `cfg_target_abi` REVERT: 84e435a879c Add `#[rustc_no_mir_inline]` for standard library UB checks REVERT: 02dc95fe50d Forbid use of `extern "C-unwind"` inside standard library REVERT: 17b07c4384f library: use `addr_of!` REVERT: 0a0d0837b0f update stdarch REVERT: d076d5fa0b6 Fix incorrect doc of ScopedJoinHandle::is_finished REVERT: 50561849715 Auto merge of #119536 - Jules-Bertholet:const-barrier, r=dtolnay REVERT: a867d469af7 std: make `ReentrantLock` public REVERT: c4e8b13aae8 Auto merge of #121303 - GrigorenkoPV:static_mut_refs, r=oli-obk,RalfJung REVERT: bd29aa0936a Auto merge of #121514 - matthiaskrgr:rollup-5f0vhv7, r=matthiaskrgr REVERT: 2eb9b374bf2 Rollup merge of #121498 - flba-eb:make_timespec_capping_public, r=Nilstrieb REVERT: d41b66881dc moved tests file REVERT: 0e9f348ebbb Get rid of some `#[allow(static_mut_refs)]` REVERT: aaa39933ec7 Auto merge of #121454 - reitermarkus:generic-nonzero-library, r=dtolnay REVERT: 03061ef1638 Make timespec capping public to crate::sys REVERT: 34f5355cb0e remove repetitive words REVERT: 381c411033b Auto merge of #120730 - estebank:confusable-api, r=oli-obk REVERT: 73892694ff0 Use Itanium ABI for thrown exceptions REVERT: 0fcf3ddee07 Unconditionally pass -wasm-enable-eh REVERT: 16e190ddf45 std support for wasm32 panic=unwind REVERT: fd0a734571d Add `flatmap`/`flat_map` -> `and_then` suggestions REVERT: 3760b37731b On type error of method call arguments, look at confusables for suggestion REVERT: a765284214e Add `rustc_confusables` annotations to some stdlib APIs REVERT: 6fde7096568 Rollup merge of #121439 - jrudolph:patch-1, r=bjorn3 REVERT: c7f7d3ff646 Fix example. REVERT: d6edf7add65 Use generic `NonZero` everywhere else. REVERT: 1d649b8071b Use generic `NonZero` everywhere in `alloc`. REVERT: 7c87cda165b Use generic `NonZero` everywhere in `std`. REVERT: a1188703ccd Use generic `NonZero` everywhere in `core`. REVERT: 6837b824cdc Auto merge of #121309 - Nilstrieb:inline-all-the-fallbacks, r=oli-obk REVERT: 6ab608963d2 Fix typo in metadata.rs doc comment REVERT: 09923461c9e Add std::ffi::c_str modules REVERT: c79c2703755 Auto merge of #117174 - Ayush1325:uefi-stdio-improve, r=workingjubilee REVERT: 2d5ed24d4f5 Auto merge of #121223 - RalfJung:simd-intrinsics, r=Amanieu REVERT: af104d23cac Auto merge of #118634 - Jules-Bertholet:box-allocator-static, r=Amanieu REVERT: d6c3d196099 Always use WaitOnAddress on Win10+ REVERT: fa98c50df21 os::net: expanding TcpStreamExt for Linux with `tcp_deferaccept`. REVERT: d5bb2e1798c remove simd_reduce_{min,max}_nanless REVERT: ae3a50b6122 rename ptr::invalid -> ptr::without_provenance REVERT: 6bcbec3c99e Remove unnecessary map_err REVERT: 3361dcfe9d9 TryReserveError to ErrorKind::OutOfMemory REVERT: 6abdde9985a make simd_reduce_{mul,add}_unordered use only the 'reassoc' flag, not all fast-math flags REVERT: d14435793d1 intrinsics::simd: add missing functions REVERT: 07d748e4f33 Auto merge of #121383 - Dylan-DPC:rollup-735p4u4, r=Dylan-DPC REVERT: 6642b854bbe Auto merge of #120718 - saethlin:reasonable-fast-math, r=nnethercote REVERT: ab621b911bc Rollup merge of #121361 - pitaj:diag_items-legacy_numeric_constants, r=Nilstrieb REVERT: 511fe47e8ea Stabilize `LazyCell` and `LazyLock` (`lazy_cell`) REVERT: c817ed5d9ca Delete architecture-specific memchr code in std::sys REVERT: 9f4fae97f03 diagnostic items for legacy numeric modules REVERT: 2fbcb3b1266 Add extra detail to field comment REVERT: e46d3d17881 Reduce alignment of TypeId to u64 alignment REVERT: 2b3ae2ab839 Rollup merge of #121352 - malobre:patch-1, r=Nilstrieb REVERT: b200b05e1e7 Rollup merge of #121277 - reitermarkus:generic-nonzero-convert-num, r=dtolnay REVERT: 31829b0c723 Rollup merge of #119203 - farnoy:simd-masked-intrinsic-docfix, r=RalfJung REVERT: e0cc93ee302 Add "algebraic" versions of the fast-math intrinsics REVERT: 878cefd56e5 docs: add missing "the" to `str::strip_prefix` doc REVERT: 21a5e604aed Auto merge of #121345 - Nilstrieb:rollup-reb0xge, r=Nilstrieb REVERT: 70e9226dbfa Add examples for some methods on slices REVERT: f06f11f81c9 Rollup merge of #121302 - GrigorenkoPV:refmutl, r=bjorn3 REVERT: f393d47cecd Rollup merge of #121241 - reitermarkus:generic-nonzero-traits, r=dtolnay REVERT: 788e34c45a8 Rollup merge of #121196 - Nilstrieb:the-clever-solution, r=saethlin REVERT: 37a66b0d4c0 Auto merge of #120863 - saethlin:slice-get-checked, r=the8472 REVERT: 0296e662d32 fix doc link REVERT: 8e5ea63a25c Rollup merge of #121311 - Nilstrieb:is-it-overlapping, r=saethlin REVERT: 74fa4671ea0 Rollup merge of #121310 - GrigorenkoPV:doc-smallfix, r=Nilstrieb REVERT: d0650533cc3 A much simpler version of write REVERT: b9a2ed212d9 remove const REVERT: 74a39dc05c7 add safety text REVERT: 64d9e168071 Fix inlining issue for non-const case REVERT: b388b1b177b Use intrinsic REVERT: 13fa1a28ad1 perf: improve write_fmt to handle simple strings REVERT: 9e47cf450d3 Add more inline(always) to fix opt-level=z test on wasm32 REVERT: 6ccbbc6e398 Convert debug_assert_nounwind to intrinsics::debug_assertions REVERT: c5b24f002c9 Auto merge of #121185 - GuillaumeGomez:update-stdarch, r=Amanieu REVERT: 4b548a2ae73 Make `is_nonoverlapping` `#[inline]` REVERT: b70f8e9cfc0 Make intrinsic fallback bodies cross-crate inlineable REVERT: 1491cb4d8ad Remove an old hack for rustdoc REVERT: e354b122cbe Auto merge of #121177 - joboet:move_pal_locks, r=ChrisDenton REVERT: eeb54280f18 Always inline check in `assert_unsafe_precondition` with cfg(debug_assertions) REVERT: 4937390dcf6 Remove `RefMutL` hack in `proc_macro::bridge` REVERT: e3442a7867a Rollup merge of #121272 - pitaj:diag_items-legacy_numeric_constants, r=Nilstrieb REVERT: 2586853a5f4 Rollup merge of #121041 - Nilstrieb:into-the-future-of-2024, r=Mark-Simulacrum REVERT: f31070073a2 Rollup merge of #119808 - GnomedDev:encode-charsearcher-size-in-type, r=Mark-Simulacrum REVERT: dc620332a7e Update stdarch submodule REVERT: 6b40c3d6539 Refactor trait implementations in `core::convert::num`. REVERT: 045057daaf9 Auto merge of #105917 - a1phyr:read_chain_more_impls, r=workingjubilee REVERT: bd70d763169 Clarify/add `must_use` message for Rc/Arc/Weak::into_raw. REVERT: b950a4056f1 Auto merge of #121269 - calebzulawski:sync-portable-simd-2024-02-18, r=Mark-Simulacrum REVERT: 56b90f47345 Fix error in push docs REVERT: 3d72a268758 Auto merge of #121101 - GnomedDev:dyn-small-c-string, r=Nilstrieb REVERT: 8d958dd5216 Add `Future` and `IntoFuture` to the 2024 prelude REVERT: 0e82369b52c diagnostic items for legacy numeric constants REVERT: b3bbcdeec36 Dyn erase at call site REVERT: 1b069b63d4f Add some comments to prevent regression REVERT: 7653d39a26d Reduce monomorphisation bloat in small_c_string REVERT: a6c89ed6adf Rollup merge of #121266 - SabrinaJewson:easy-syscall-aliases, r=Mark-Simulacrum REVERT: 5ef0db76cce Rollup merge of #121224 - hi-rustin:rustin-patch-unit-binding, r=Mark-Simulacrum REVERT: 910d274aa9c Rollup merge of #118569 - blyxxyz:platform-os-str-slice, r=Mark-Simulacrum REVERT: 4f721156b2b Merge commit '649110751ef4f27440d7cc711b3e07d11bf02d4a' into sync-portable-simd-2024-02-18 REVERT: 8dd16f53429 Add uncontroversial syscall doc aliases to std docs REVERT: 150523e5b46 Auto merge of #117772 - surechen:for_117448, r=petrochenkov REVERT: 85280706541 fix typo in push documentation REVERT: 513b920c7ee intradoc link for vec REVERT: 926f36b1ab4 time complexity for insert REVERT: b4ccf7db259 time complexity for pop REVERT: 8e6711c1751 time complexity for push_within_capacity REVERT: 31249e22cdf time complexity for push REVERT: 30336a77f73 By tracking import use types to check whether it is scope uses or the other situations like module-relative uses, we can do more accurate redundant import checking. REVERT: 597c2d255fd Auto merge of #121034 - obeis:improve-static-mut-ref, r=RalfJung REVERT: e80218906b8 Improve wording of static_mut_ref REVERT: 29c5be12c47 Auto merge of #118264 - lukas-code:optimized-draining, r=the8472 REVERT: 998f195b19b Implement `NonZero` traits generically. REVERT: 74527e99fbc Auto merge of #121204 - cuviper:flatten-one-shot, r=the8472 REVERT: e911cad4e7d Rollup merge of #121149 - SebastianJL:patch-1, r=Mark-Simulacrum REVERT: 4989bc38447 Rollup merge of #120952 - saethlin:vec-into-iter, r=the8472 REVERT: 09f2c5067fd Auto merge of #121232 - RalfJung:miri, r=RalfJung REVERT: 263cf10db7f Allow newly added non_local_definitions in std REVERT: 6d047e54069 Rollup merge of #121192 - oli-obk:intrinsics2.0, r=WaffleLapkin REVERT: a70e0963daa Rollup merge of #121187 - Takashiidobe:takashi/examples-for-quickselect, r=Nilstrieb REVERT: 80a94e4e2a8 Rollup merge of #119032 - smmalis37:patch-1, r=ChrisDenton REVERT: b0898be1180 Remove unnecessary unit binding REVERT: 2a42861b3f2 Merge from rustc REVERT: 0fda857591d Auto merge of #120563 - reitermarkus:generic-nonzero-get, r=dtolnay REVERT: b19e222bdbe Add an example to demonstrate how Rc::into_inner works REVERT: 6041bcea731 Auto merge of #120741 - a1phyr:safe_buffer_advance, r=m-ou-se REVERT: 89767fa283d Clarify the flatten specialization comment REVERT: df242d936cd Remove cfg_attr REVERT: d66aec0606d Use a hardcoded constant instead of calling OpenProcessToken. REVERT: 0464596b368 Give the (`un`)`likely` intrinsics fallback bodies REVERT: 38af756b834 Give the `assume` intrinsic a fallback body REVERT: 4de18f1ac27 Specialize flattening iterators with only one inner item REVERT: fbd7d663f57 Don't use mem::zeroed in vec::IntoIter REVERT: a22b06ba375 Add examples to document the return type of `select_nth_unstable`, `select_nth_unstable_by`, and `select_nth_unstable_by_key`. REVERT: 7840f483be4 Auto merge of #116385 - kornelski:maybe-rename, r=Amanieu REVERT: 0a915eb5e34 address review comments REVERT: 01fd99079c5 outline large copies REVERT: ae0b3dd4ba1 reduce branchiness REVERT: b46a88ea0cd reduce amount of math REVERT: 7676dfd132e simplify codegen for trivially droppable types REVERT: 03d6ce10579 Auto merge of #120538 - kornelski:read-not-exact, r=m-ou-se REVERT: 1a46f7213bb std: move locks to `sys` on platforms without threads REVERT: c426d14e7f8 std: move locks to `sys` on xous REVERT: cb2a73347c7 std: move locks to `sys` on Windows REVERT: aabb6094b6d std: move locks to `sys` on UNIX and other futex platforms REVERT: 653f7b597dd std: move locks to `sys` on teeos REVERT: 61659af728c std: move locks to `sys` on SGX REVERT: a8d0e2e9ea5 std: move locks to `sys` on µITRON REVERT: b457779990a Auto merge of #120500 - oli-obk:intrinsics2.0, r=WaffleLapkin REVERT: 9981b0eceb3 Auto merge of #120486 - reitermarkus:use-generic-nonzero, r=dtolnay REVERT: baf1bbfd05f Merge from rustc REVERT: b484e9658a5 Auto merge of #120889 - Ayush1325:uefi-instant, r=joshtriplett REVERT: f3af02651df Rollup merge of #121155 - tspiteri:strict-doc-overflow, r=Nilstrieb REVERT: 4773c9e8a10 Rollup merge of #120971 - PizzasBear:patch-1, r=Nilstrieb REVERT: a0145d48d44 Rollup merge of #120777 - Marcondiro:unicode15-1, r=Manishearth REVERT: 143a39d9c5c doc: panicking division by zero examples for unsigned strict div ops REVERT: 2f86d6ee465 doc: add note before panicking examples for strict_overflow_ops REVERT: e834b7e30c7 Auto merge of #121142 - GuillaumeGomez:rollup-5qmksjw, r=GuillaumeGomez REVERT: dcb378aca13 Fix typo in VecDeque::handle_capacity_increase() doc comment. REVERT: 71ec8f8397c Add slice::try_range REVERT: 6e6fa8e1d20 Auto merge of #119863 - tmiasko:will-wake, r=m-ou-se REVERT: b9a4a12f92b Rollup merge of #121120 - nnethercote:LitKind-Err-guar, r=fmease REVERT: 68b5e7bc17c Rollup merge of #120672 - devnexen:update_thread_stack_guardpages_fbsd, r=m-ou-se REVERT: 882dc683c69 Rollup merge of #120505 - Amanieu:fix-btreemap-cursor-remove, r=m-ou-se REVERT: 6a16d9dacbb Rollup merge of #120449 - udoprog:document-unsized-rc-arc-from-raw, r=m-ou-se REVERT: 26b44e1c0c1 Add ASCII fast-path for `char::is_grapheme_extended` REVERT: 6cba163d299 Rollup merge of #121098 - ShoyuVanilla:thread-local-unnecessary-else, r=Nilstrieb REVERT: 1a1ae7f0945 Rollup merge of #121082 - peterjoel:atomic-docs, r=cuviper REVERT: 50fbdb3f216 Rollup merge of #118749 - ChrisDenton:winsys, r=cuviper REVERT: 6e2c4f48cc5 Rollup merge of #111106 - Stargateur:doc/format_args, r=m-ou-se REVERT: 926ab97d2c0 Replace `NonZero::<_>::new` with `NonZero::new`. REVERT: 7870dc47f88 Use generic `NonZero` internally. REVERT: 4e6cd3e02b0 Add `ErrorGuaranteed` to `ast::LitKind::Err`, `token::LitKind::Err`. REVERT: 80913e18ce5 Clarified docs on non-atomic oprations on owned/mut refs to atomics REVERT: 05b5eff85e1 Merge from rustc REVERT: ad6965a4f1e Remove unnecessary else block from `thread_local!` expanded code REVERT: 71d02d48dff Auto merge of #121078 - oli-obk:rollup-p11zsav, r=oli-obk REVERT: f3650d6e46a Rollup merge of #121073 - IgorLaborieWefox:patch-1, r=workingjubilee REVERT: dc35347395f Rollup merge of #121024 - joseluis:feat-asciichar-default, r=scottmcm REVERT: dab1236f4d5 Rollup merge of #118890 - Amanieu:allocator-lifetime, r=Mark-Simulacrum REVERT: 187f847d781 Rollup merge of #118738 - devnexen:netbsd10_update, r=cuviper REVERT: 8c0023d8117 Rollup merge of #116387 - kpreid:wake-doc, r=cuviper REVERT: 6a6870751bd Auto merge of #100603 - tmandry:zst-guards, r=dtolnay REVERT: 34196f6d2ac Automatically sort windows_sys bindings REVERT: ee23acf6bc2 Add windows_sys readme REVERT: 08e47326af2 Move windows_sys.lst to bindings.txt REVERT: b0b371b1b7c Fix typos in `OneLock` doc REVERT: 8535e57e55e Fix incorrect use of `compile_fail` REVERT: e83394c84cf Add information about allocation lifetime to Allocator::allocate REVERT: de3bcca36f4 implement `Default` for `AsciiChar` REVERT: 236c25e8033 Implement Instant for UEFI REVERT: 0b5ada2b22a Auto merge of #121003 - matthiaskrgr:rollup-u5wyztn, r=matthiaskrgr REVERT: 821af2ba024 Rollup merge of #120986 - tshepang:extraneous, r=cuviper REVERT: ca63ba97a0d Rollup merge of #120967 - LeoDog896:master, r=cuviper REVERT: 0b357246fd2 Merge from rustc REVERT: 0fa295ae27a Auto merge of #120938 - Ayush1325:uefi-thread, r=joboet,Nilstrieb REVERT: fa026317a39 docs: use correct link, use secondary example REVERT: 2f68e0a1e11 iterator.rs: remove "Basic usage" text REVERT: 9fd456ccecb Support safe intrinsics with fallback bodies REVERT: 92c4f8451fe Give const_deallocate a default body REVERT: e4e14afe33d Teach llvm backend how to fall back to default bodies REVERT: e78e22d4dd5 Check signature of intrinsics with fallback bodies REVERT: b9a7dbf8125 Rollup merge of #120936 - ripytide:master, r=Amanieu REVERT: 2ee0698fb52 constify a couple thread_local statics REVERT: b4d39ca1fdb style: fmt REVERT: aeea8fe6af4 Clarify the lifetimes of allocations returned by the `Allocator` trait REVERT: b707b6c6d29 Fix comment in core/src/str/validations.rs REVERT: 985e87ec2df docs: mention round-to-even in precision formatting REVERT: 9a03ed37b5f Merge from rustc REVERT: 0a062ec3292 Auto merge of #110211 - joboet:queue_lock, r=Amanieu REVERT: 2f6532935af Implement intrinsics with fallback bodies REVERT: 6a1bbb0daa7 Rollup merge of #120888 - saethlin:unsafe-precondition-cleanup, r=RalfJung REVERT: e6f1dc2fcc8 Rollup merge of #120880 - RalfJung:vtable-fnptr-partialeq, r=cuviper REVERT: 5d7b839d85a Rollup merge of #120740 - ChrisDenton:cmaths, r=Mark-Simulacrum REVERT: 4c4ec2b7084 Rollup merge of #110483 - tleibert:thin-box-try-new, r=dtolnay REVERT: 1696700c69a std: use `stream_position` where applicable REVERT: 0b06390f4de add comparison warning to RawWakerVTable as well REVERT: d41a9487d38 fix intra-doc links REVERT: e870089a8e4 Implement sys/thread for UEFI REVERT: bb24215c837 Auto merge of #120903 - matthiaskrgr:rollup-tmsuzth, r=matthiaskrgr REVERT: 55ec6457c7d Cleanup around the new assert_unsafe_precondition REVERT: d95ae4eb60a fix incorrect doctest REVERT: 170a28a257d improve `btree_cursors` functions documentation REVERT: 0125017988d add doc-comment to `unlock_queue` REVERT: 2a9655399c5 std: enabling new netbsd (10) calls. REVERT: c8634c236cd Rollup merge of #120459 - rytheo:handle-conversion-docs, r=Mark-Simulacrum REVERT: 1d5ef4a9764 Rollup merge of #120307 - djc:duration-constructors, r=Mark-Simulacrum REVERT: 414edebf766 Rollup merge of #119449 - Nilstrieb:library-clippy, r=cuviper REVERT: f2e9990ceae Rollup merge of #119242 - BenWiederhake:dev-from-nanos, r=joshtriplett REVERT: 99e6261e199 Rollup merge of #118307 - scottmcm:tuple-eq-simpler, r=joshtriplett REVERT: a418c46bd84 Rollup merge of #117740 - majaha:format_docs, r=joshtriplett REVERT: 194da2e2fb4 Remove the link. REVERT: b6fb05a18e2 URL-encode chars in fragment. REVERT: 7bfd06ba1d9 Additional doc links and explanation of `Wake`. REVERT: 19a6b075dfa Merge from rustc REVERT: 90aaf184f38 Auto merge of #120232 - c272:json-buildstd, r=Mark-Simulacrum REVERT: d2d538a4f96 Rollup merge of #119213 - RalfJung:simd_shuffle, r=workingjubilee REVERT: 2ed3ac079d6 add note on comparing vtables / function pointers REVERT: 8c9555c9058 Rollup merge of #120823 - LegionMammal978:clarify-atomic-align, r=RalfJung REVERT: 02caf1fe8f7 Rollup merge of #120764 - Alfriadox:master, r=m-ou-se REVERT: 35ef0688244 various docs tweaks REVERT: cb302e0fc65 simd_scatter: mention left-to-right order REVERT: eb8fc13d691 add more missing simd intrinsics REVERT: 9fd3c75e19f simd intrinsics: add simd_shuffle_generic REVERT: 3f027117151 Stabilize slice_split_at_unchecked REVERT: df4ba99b376 Auto merge of #120712 - compiler-errors:async-closures-harmonize, r=oli-obk REVERT: f0ddef4a72e Merge from rustc REVERT: 6b589c4430d Change wording REVERT: f9e40ce4eb5 Auto merge of #120852 - matthiaskrgr:rollup-01pr8gj, r=matthiaskrgr REVERT: 39f26bdfcfc std::thread update freebsd stack guard handling. REVERT: 85a5f3a711c Rollup merge of #120815 - camsteffen:inspect-docs, r=m-ou-se REVERT: e7b1bc00c88 Rollup merge of #120776 - joboet:move_pal_path, r=ChrisDenton REVERT: 266b53157db Rollup merge of #120351 - Ayush1325:uefi-time, r=m-ou-se REVERT: 04889f625c4 Auto merge of #120676 - Mark-Simulacrum:bootstrap-bump, r=clubby789 REVERT: 8eeb7d733b2 address review comments REVERT: 4566d41aaee Bump Unicode to version 15.1.0, regenerate tables REVERT: 61833dff7f5 be more explicit about why adding backlinks eagerly makes sense REVERT: 6835f46f68d Improve Option::inspect docs REVERT: 9987f16537b Auto merge of #120843 - matthiaskrgr:rollup-med37z5, r=matthiaskrgr REVERT: f87fa6d677b format using latest rustfmt REVERT: 4a2ab6d1c5e inline some single-use functions, add documentation REVERT: d37b71e54cc queue_rwlock: use a separate `QUEUE_LOCKED` bit to synchronize waiter queue updates REVERT: b1a5f78b1ec use exponential backoff in `lock_contended` REVERT: 56e1efb8af3 immediately register writer node if threads are queued REVERT: ce581cca729 avoid unnecessary `Thread` handle allocation REVERT: db96f0366bd use braces to make operator precedence less ambiguous REVERT: dc2d0509e25 adjust code documentation REVERT: 132e36aad77 std: replace pthread `RwLock` with custom implementation inspired by usync REVERT: 88dbefe419a Rollup merge of #120809 - reitermarkus:generic-nonzero-constructors, r=Nilstrieb REVERT: d13b542ad25 Rollup merge of #120308 - utkarshgupta137:duration-opt, r=m-ou-se REVERT: 816944b6d47 Auto merge of #120594 - saethlin:delayed-debug-asserts, r=oli-obk REVERT: 95fc1c72851 Auto merge of #120238 - joboet:always_confirm_lock_success, r=Mark-Simulacrum REVERT: ea50f6e26d0 Clarify that atomic and regular integers can differ in alignment REVERT: f85909649a8 Add and use Unique::as_non_null_ptr REVERT: 1b7c1082604 Make `NonZero::get` generic. REVERT: fe47f1439c4 Use `transmute_unchecked` in `NonZero::new`. REVERT: 0bd39644c29 Reduce use of NonNull::new_unchecked in library/ REVERT: c04cba0ce9d Remove a now-obviated debug_assert! REVERT: 94a8293f01c Rewrite assert_unsafe_precondition around the new intrinsic REVERT: ab5ca413dc4 Add a new debug_assertions intrinsic REVERT: 1abe4f582a9 Step all bootstrap cfgs forward REVERT: 37f3ad90f22 Bump version placeholders REVERT: 6412eff99cd std: move path into `sys` REVERT: 0839a16de98 Auto merge of #120558 - oli-obk:missing_impl_item_ice, r=estebank REVERT: e79c64e92c8 Fix whitespace issues that tidy caught REVERT: 4ecc5c5b08d Add documentation on `str::starts_with` REVERT: 420b5d8c763 Auto merge of #120521 - reitermarkus:generic-nonzero-constructors, r=dtolnay REVERT: 00d45b89d67 Auto merge of #120381 - fee1-dead-contrib:reconstify-add, r=compiler-errors REVERT: 82b7f74a159 Make `io::BorrowedCursor::advance` safe REVERT: fa1947f78b2 Make cmath.rs a single file REVERT: 4c2ea7bc4be Replace `transmute_copy` with `ptr::read`. REVERT: a9847020e7b Don't use `assert_unsafe_precondition` twice. REVERT: 69b52185f26 Auto merge of #120527 - GnomedDev:atomicu32-handle, r=petrochenkov REVERT: 3ed3e1bb71a Make `NonZero` constructors generic. REVERT: 2edf2118adc Simplify `impl_zeroable_primitive` macro. REVERT: b825d658298 Update tests REVERT: 3b0b747eb3e Auto merge of #117905 - RalfJung:no-const-mut, r=lcnr REVERT: cf1c72f3202 Harmonize blanket implementations for AsyncFn* traits REVERT: 0039eee64dd Auto merge of #120361 - compiler-errors:async-closures, r=oli-obk REVERT: 26abc5319c1 Auto merge of #120326 - tmandry:abort-in-tests, r=cuviper REVERT: 04ebdf56df1 Bless tests, add comments REVERT: 0eccda24d9a Teach typeck/borrowck/solvers how to deal with async closures REVERT: fef14350edb revert stabilization of const_intrinsic_copy REVERT: 02cfedd4806 Auto merge of #117372 - Amanieu:stdarch_update, r=Mark-Simulacrum REVERT: da24d528151 Remove some invalid cfg(doc) code REVERT: 7e09db626eb Rollup merge of #120657 - mu001999:clean, r=Nilstrieb REVERT: 3df14c076d0 Rollup merge of #120384 - wackbyte:array-equality-generics, r=Mark-Simulacrum REVERT: 4ba91a341b9 Rollup merge of #118960 - tvallotton:local_waker, r=Mark-Simulacrum REVERT: c0bffc467e6 Rollup merge of #115386 - RalfJung:partial-eq-chain, r=dtolnay REVERT: ae215772f37 Rollup merge of #113833 - WiktorPrzetacznik:master, r=dtolnay REVERT: 4221058a4ad Rollup merge of #120607 - conradludgate:fix-120603, r=dtolnay REVERT: 6c615798209 Rollup merge of #120572 - pheki:update-libc, r=Mark-Simulacrum REVERT: 9cfdb5a3413 Rollup merge of #120458 - rytheo:cstr-conversion-doc, r=Mark-Simulacrum REVERT: 063fcaccc5b Rollup merge of #119481 - romanows:fix-doc-select-nth-unstable, r=Mark-Simulacrum REVERT: 017ae66f9dc Remove unused struct REVERT: 4997a6fc271 Auto merge of #120624 - matthiaskrgr:rollup-3gvcl20, r=matthiaskrgr REVERT: 9d9e19a4617 Reconstify `Add` REVERT: 14f6ef0c350 Rollup merge of #120528 - GnomedDev:atomicu8-backtrace-style, r=cuviper REVERT: f578f843041 Rollup merge of #120523 - a1phyr:improve_read_buf_exact, r=the8472 REVERT: 66ef6117b29 add another test to make sure it still works with full reads REVERT: df313690e4f fix #120603 by adding a check in default_read_buf REVERT: d341004d0d7 Docs for std::ptr::slice_from_raw_parts REVERT: c00a2cfdca7 Update libc to 0.2.153 REVERT: 3475147f927 Revert unsound libcore changes of #119911 REVERT: 58d486dfdc4 Make File::read_to_end less special REVERT: 923702359df Store SHOULD_CAPTURE as AtomicU8 REVERT: 40ae652e04c Switch OwnedStore handle count to AtomicU32 REVERT: 58ba7c6b6d6 Rollup merge of #120430 - devnexen:fix_tls_dtor_fbsd, r=cuviper REVERT: 00e2eeced60 Rollup merge of #120355 - the8472:doc-vec-fromiter, r=cuviper REVERT: fa9df694f62 Improve `io::Read::read_buf_exact` error case REVERT: 55c2280c052 Fix BTreeMap's Cursor::remove_{next,prev} REVERT: 3e8bd0c0893 Rollup merge of #120485 - chenyukang:yukang-add-query-instability-check, r=michaelwoerister REVERT: 1f82ee313cb Rollup merge of #120445 - Nemo157:arc-plug, r=Mark-Simulacrum REVERT: 8fe24a79470 Rollup merge of #120434 - fmease:revert-speeder, r=petrochenkov REVERT: ed0c6d99493 Rollup merge of #120295 - reitermarkus:remove-ffi-nonzero, r=dtolnay REVERT: f6e1c6bb945 Rollup merge of #120452 - alexcrichton:update-windows-seek-write-docs, r=ChrisDenton REVERT: c076f5a496e Rollup merge of #120424 - RalfJung:raw-ptr-meta, r=Nilstrieb REVERT: 362bcc93d3d Rollup merge of #119991 - kornelski:endless-read, r=the8472 REVERT: d5c992db4d1 Auto merge of #117925 - kornelski:read-to-oom, r=Amanieu REVERT: e1060193b0a Disable conversions between portable_simd and stdarch on big-endian ARM REVERT: 0e31f592f2c add missing potential_query_instability for keys and values in hashmap REVERT: 9e63613f632 Add stdarch_wasm_atomic_wait feature in std REVERT: 902bfb8f5e2 Update feature names for new stdarch REVERT: 8af5a729181 Update stdarch submodule REVERT: b0f911772fe Rollup merge of #120462 - mu001999:clean, r=Nilstrieb REVERT: 194dc82a92e Rollup merge of #120373 - HTGAzureX1212:HTGAzureX1212/issue-120040, r=ChrisDenton REVERT: ebed0b38c3d add extra check for invalid handle in ReadDir::next REVERT: e797c208a76 make modifications as per reviews REVERT: f9853e319bd fix REVERT: 414e7ab7477 remove redundant call to Error::last_os_error REVERT: 6bb34ba05ca fix issue 120040 REVERT: d91014cffee Convert `Unix{Datagram,Stream}::{set_}passcred()` to per-OS traits REVERT: 7c219da2111 Implement DoubleEnded and ExactSize for Take and Take REVERT: fd9367b287e Add Read Impl for &Stdin git-subtree-dir: library git-subtree-split: b102eb9761121691d3f6a7b6c4485023bda2808d --- Cargo.lock | 57 +- Cargo.toml | 2 +- alloc/Cargo.toml | 2 +- alloc/benches/lib.rs | 3 +- alloc/src/alloc.rs | 5 +- alloc/src/boxed.rs | 64 +- alloc/src/boxed/convert.rs | 4 +- alloc/src/collections/binary_heap/mod.rs | 11 +- alloc/src/collections/btree/map.rs | 38 +- alloc/src/collections/btree/map/entry.rs | 110 +- alloc/src/collections/btree/node.rs | 6 +- alloc/src/collections/btree/set.rs | 115 +- alloc/src/collections/btree/set/entry.rs | 388 +++ alloc/src/collections/linked_list.rs | 9 +- alloc/src/collections/vec_deque/mod.rs | 23 +- alloc/src/ffi/c_str.rs | 41 +- alloc/src/ffi/mod.rs | 2 +- alloc/src/fmt.rs | 2 + alloc/src/lib.rs | 18 +- alloc/src/macros.rs | 7 +- alloc/src/raw_vec.rs | 55 +- alloc/src/rc.rs | 306 ++- alloc/src/rc/tests.rs | 4 +- alloc/src/slice.rs | 2 + alloc/src/string.rs | 259 +- alloc/src/sync.rs | 48 +- alloc/src/task.rs | 1 - alloc/src/vec/extract_if.rs | 50 +- alloc/src/vec/is_zero.rs | 15 +- alloc/src/vec/mod.rs | 142 +- alloc/{src/alloc/tests.rs => tests/alloc.rs} | 5 +- alloc/tests/boxed.rs | 2 +- .../ffi/c_str/tests.rs => tests/c_str2.rs} | 9 +- .../collections/binary_heap.rs} | 8 +- alloc/tests/collections/mod.rs | 1 + alloc/tests/lib.rs | 29 +- alloc/{src/tests.rs => tests/misc_tests.rs} | 0 alloc/tests/sort/tests.rs | 2 +- alloc/{src/sync/tests.rs => tests/sync.rs} | 14 +- alloc/tests/testing/crash_test.rs | 80 + alloc/tests/testing/mod.rs | 1 + alloc/tests/vec.rs | 98 +- backtrace | 2 +- core/Cargo.toml | 3 +- core/benches/ascii/is_ascii.rs | 47 +- core/benches/num/int_pow/mod.rs | 2 +- core/src/alloc/layout.rs | 19 +- core/src/any.rs | 14 +- core/src/arch.rs | 26 + core/src/array/iter.rs | 8 +- core/src/array/mod.rs | 24 +- core/src/bool.rs | 49 + core/src/cell.rs | 25 +- core/src/cell/lazy.rs | 4 +- core/src/cell/once.rs | 12 +- core/src/char/methods.rs | 29 +- core/src/cmp.rs | 2 +- core/src/convert/mod.rs | 2 + core/src/error.rs | 6 +- core/src/ffi/c_str.rs | 60 +- core/src/ffi/mod.rs | 137 +- core/src/ffi/va_list.rs | 19 + core/src/fmt/float.rs | 6 +- core/src/fmt/mod.rs | 432 +++- core/src/fmt/rt.rs | 46 +- core/src/future/async_drop.rs | 3 +- core/src/future/future.rs | 2 +- core/src/hash/mod.rs | 7 +- core/src/hint.rs | 93 +- core/src/intrinsics/fallback.rs | 112 + core/src/intrinsics/mir.rs | 36 +- core/src/intrinsics/mod.rs | 2135 ++++++++++------- core/src/intrinsics/simd.rs | 14 + core/src/io/borrowed_buf.rs | 14 +- core/src/iter/adapters/filter_map.rs | 4 +- core/src/iter/adapters/flatten.rs | 34 +- core/src/iter/sources/from_fn.rs | 2 + core/src/iter/sources/once.rs | 3 +- core/src/iter/sources/successors.rs | 1 + core/src/iter/traits/collect.rs | 354 +-- core/src/iter/traits/iterator.rs | 11 +- core/src/lib.rs | 35 +- core/src/macros/mod.rs | 3 +- core/src/marker.rs | 61 +- core/src/mem/maybe_uninit.rs | 603 +++-- core/src/mem/mod.rs | 21 +- core/src/mem/transmutability.rs | 3 +- core/src/net/display_buffer.rs | 4 +- core/src/net/ip_addr.rs | 14 +- core/src/num/f128.rs | 5 +- core/src/num/f16.rs | 5 +- core/src/num/f32.rs | 38 +- core/src/num/f64.rs | 24 +- core/src/num/flt2dec/mod.rs | 48 +- core/src/num/flt2dec/strategy/dragon.rs | 10 +- core/src/num/flt2dec/strategy/grisu.rs | 10 +- core/src/num/int_macros.rs | 149 +- core/src/num/mod.rs | 205 +- core/src/num/niche_types.rs | 168 ++ core/src/num/nonzero.rs | 45 +- core/src/num/uint_macros.rs | 196 +- core/src/ops/arith.rs | 15 +- core/src/ops/async_function.rs | 16 +- core/src/ops/control_flow.rs | 17 +- core/src/ops/deref.rs | 55 +- core/src/ops/drop.rs | 3 +- core/src/ops/mod.rs | 1 - core/src/option.rs | 18 +- core/src/panic.rs | 3 +- core/src/panic/panic_info.rs | 2 +- core/src/panicking.rs | 27 +- core/src/pat.rs | 2 +- core/src/pin.rs | 30 +- core/src/prelude/mod.rs | 4 +- core/src/primitive_docs.rs | 10 +- core/src/ptr/alignment.rs | 7 - core/src/ptr/const_ptr.rs | 78 +- core/src/ptr/metadata.rs | 6 +- core/src/ptr/mod.rs | 125 +- core/src/ptr/mut_ptr.rs | 104 +- core/src/ptr/non_null.rs | 122 +- core/src/ptr/unique.rs | 1 - core/src/result.rs | 13 +- core/src/slice/ascii.rs | 74 +- core/src/slice/iter.rs | 103 +- core/src/slice/memchr.rs | 4 - core/src/slice/mod.rs | 387 ++- core/src/str/converts.rs | 5 +- core/src/str/lossy.rs | 4 +- core/src/str/mod.rs | 8 +- core/src/sync/atomic.rs | 10 +- core/src/task/wake.rs | 16 +- core/src/time.rs | 96 +- core/src/ub_checks.rs | 2 - core/src/unicode/printable.py | 53 +- core/src/unicode/unicode_data.rs | 3 - core/src/unsafe_binder.rs | 25 + core/tests/fmt/mod.rs | 31 + core/tests/hash/mod.rs | 15 +- core/tests/intrinsics.rs | 68 + core/tests/iter/adapters/take.rs | 2 +- core/tests/iter/traits/iterator.rs | 25 + core/tests/lib.rs | 18 +- core/tests/mem.rs | 32 +- core/tests/num/i128.rs | 2 +- core/tests/num/i16.rs | 2 +- core/tests/num/i32.rs | 2 +- core/tests/num/i64.rs | 2 +- core/tests/num/i8.rs | 2 +- core/tests/num/int_macros.rs | 100 +- core/tests/num/uint_macros.rs | 15 + core/tests/ptr.rs | 65 +- core/tests/slice.rs | 70 +- panic_unwind/Cargo.toml | 5 +- panic_unwind/src/gcc.rs | 2 +- panic_unwind/src/lib.rs | 5 +- panic_unwind/src/seh.rs | 2 - .../crates/core_simd/src/vendor/arm.rs | 13 +- proc_macro/src/bridge/arena.rs | 2 +- proc_macro/src/bridge/fxhash.rs | 8 +- proc_macro/src/bridge/symbol.rs | 6 - proc_macro/src/lib.rs | 80 +- proc_macro/src/quote.rs | 149 +- profiler_builtins/Cargo.toml | 5 +- profiler_builtins/src/lib.rs | 12 +- std/Cargo.toml | 10 +- std/src/collections/hash/map.rs | 34 +- std/src/collections/hash/set.rs | 30 +- std/src/env.rs | 23 +- std/src/f128.rs | 2 + std/src/f16.rs | 2 + std/src/f32.rs | 2 + std/src/f64.rs | 2 + std/src/ffi/mod.rs | 10 +- std/src/ffi/os_str.rs | 8 +- std/src/ffi/os_str/tests.rs | 2 +- std/src/fs.rs | 27 +- std/src/fs/tests.rs | 70 + std/src/io/buffered/bufreader/buffer.rs | 4 +- std/src/io/buffered/bufwriter.rs | 4 +- std/src/io/buffered/linewritershim.rs | 9 +- std/src/io/buffered/tests.rs | 18 +- std/src/io/cursor.rs | 4 +- std/src/io/error.rs | 85 +- std/src/io/error/repr_bitpacked.rs | 9 +- std/src/io/error/tests.rs | 10 +- std/src/io/mod.rs | 32 +- std/src/io/stdio.rs | 1 + std/src/io/tests.rs | 4 +- std/src/keyword_docs.rs | 122 +- std/src/lib.rs | 25 +- std/src/net/mod.rs | 2 +- std/src/net/udp.rs | 4 +- std/src/os/darwin/mod.rs | 2 +- std/src/os/emscripten/fs.rs | 2 +- std/src/os/emscripten/raw.rs | 2 - std/src/os/fd/owned.rs | 42 +- std/src/os/fd/raw.rs | 8 + std/src/os/hurd/fs.rs | 2 +- std/src/os/hurd/mod.rs | 1 + std/src/os/solid/io.rs | 27 +- std/src/os/unix/fs.rs | 5 + std/src/os/unix/net/addr.rs | 8 +- std/src/os/wasi/fs.rs | 5 +- std/src/os/windows/io/handle.rs | 8 + std/src/os/windows/io/socket.rs | 49 +- std/src/os/windows/process.rs | 328 ++- std/src/panicking.rs | 52 +- std/src/path.rs | 24 +- std/src/path/tests.rs | 4 +- std/src/pipe.rs | 140 +- std/src/prelude/common.rs | 2 +- std/src/prelude/mod.rs | 21 +- std/src/process.rs | 55 +- std/src/process/tests.rs | 14 +- std/src/rt.rs | 70 +- std/src/sync/barrier.rs | 61 +- std/src/sync/lazy_lock.rs | 3 +- std/src/sync/mod.rs | 56 +- std/src/sync/once_lock.rs | 1 + std/src/sync/poison.rs | 122 +- std/src/sync/{ => poison}/condvar.rs | 4 +- std/src/sync/{ => poison}/condvar/tests.rs | 0 std/src/sync/{ => poison}/mutex.rs | 110 +- std/src/sync/{ => poison}/mutex/tests.rs | 161 +- std/src/sync/{ => poison}/once.rs | 0 std/src/sync/{ => poison}/once/tests.rs | 0 std/src/sync/{ => poison}/rwlock.rs | 128 +- std/src/sync/{ => poison}/rwlock/tests.rs | 174 +- std/src/sys/backtrace.rs | 26 +- std/src/sys/cmath.rs | 8 + std/src/sys/pal/common/small_c_string.rs | 2 +- std/src/sys/pal/hermit/fs.rs | 24 +- std/src/sys/pal/hermit/mod.rs | 4 +- std/src/sys/pal/hermit/net.rs | 4 +- std/src/sys/pal/hermit/os.rs | 4 +- std/src/sys/pal/hermit/thread.rs | 4 +- std/src/sys/pal/hermit/time.rs | 2 +- std/src/sys/pal/sgx/fd.rs | 2 +- std/src/sys/pal/sgx/mod.rs | 4 +- std/src/sys/pal/solid/fs.rs | 27 +- std/src/sys/pal/solid/net.rs | 2 +- std/src/sys/pal/solid/os.rs | 2 +- std/src/sys/pal/teeos/mod.rs | 10 +- std/src/sys/pal/uefi/fs.rs | 344 +++ std/src/sys/pal/uefi/helpers.rs | 49 +- std/src/sys/pal/uefi/mod.rs | 3 +- std/src/sys/pal/uefi/os.rs | 12 +- std/src/sys/pal/uefi/process.rs | 10 +- std/src/sys/pal/unix/fd.rs | 2 - std/src/sys/pal/unix/fs.rs | 161 +- std/src/sys/pal/unix/kernel_copy.rs | 15 +- std/src/sys/pal/unix/l4re.rs | 2 +- std/src/sys/pal/unix/mod.rs | 3 +- std/src/sys/pal/unix/net.rs | 5 +- std/src/sys/pal/unix/os.rs | 25 +- .../sys/pal/unix/process/process_common.rs | 2 +- .../sys/pal/unix/process/process_fuchsia.rs | 8 +- std/src/sys/pal/unix/process/process_unix.rs | 10 +- .../sys/pal/unix/process/process_vxworks.rs | 2 +- std/src/sys/pal/unix/stack_overflow.rs | 9 +- std/src/sys/pal/unix/sync/condvar.rs | 172 ++ std/src/sys/pal/unix/sync/mod.rs | 16 + std/src/sys/pal/unix/sync/mutex.rs | 135 ++ std/src/sys/pal/unix/thread.rs | 29 +- std/src/sys/pal/unix/time.rs | 35 +- std/src/sys/pal/unsupported/os.rs | 4 +- std/src/sys/pal/wasi/fs.rs | 182 +- std/src/sys/pal/wasi/thread.rs | 16 +- std/src/sys/pal/wasip2/net.rs | 2 +- std/src/sys/pal/windows/args.rs | 4 +- std/src/sys/pal/windows/c/bindings.txt | 4 + std/src/sys/pal/windows/c/windows_sys.rs | 18 + std/src/sys/pal/windows/fs.rs | 188 +- std/src/sys/pal/windows/mod.rs | 8 +- std/src/sys/pal/windows/net.rs | 2 +- std/src/sys/pal/windows/os.rs | 9 +- std/src/sys/pal/windows/process.rs | 120 +- std/src/sys/pal/windows/stack_overflow.rs | 8 +- std/src/sys/pal/windows/stdio.rs | 38 +- std/src/sys/pal/windows/thread.rs | 1 + std/src/sys/pal/xous/net/dns.rs | 5 +- std/src/sys/pal/xous/net/tcplistener.rs | 36 +- std/src/sys/pal/xous/net/tcpstream.rs | 46 +- std/src/sys/pal/xous/net/udp.rs | 50 +- std/src/sys/pal/zkvm/os.rs | 4 +- std/src/sys/path/sgx.rs | 4 + std/src/sys/path/unix.rs | 11 + std/src/sys/path/unsupported_backslash.rs | 4 + std/src/sys/path/windows.rs | 6 +- std/src/sys/personality/gcc.rs | 2 +- std/src/sys/personality/mod.rs | 2 +- std/src/sys/sync/condvar/no_threads.rs | 7 +- std/src/sys/sync/condvar/pthread.rs | 210 +- std/src/sys/sync/condvar/sgx.rs | 8 +- std/src/sys/sync/mutex/no_threads.rs | 1 - std/src/sys/sync/mutex/pthread.rs | 157 +- std/src/sys/sync/mutex/sgx.rs | 4 +- std/src/sys/sync/once/futex.rs | 2 +- std/src/sys/sync/once/no_threads.rs | 3 +- std/src/sys/sync/once/queue.rs | 3 +- std/src/sys/sync/once_box.rs | 25 +- std/src/sys/sync/rwlock/no_threads.rs | 1 - std/src/sys/sync/thread_parking/pthread.rs | 167 +- std/src/sys/thread_local/key/racy.rs | 1 - std/src/sys/thread_local/key/unix.rs | 20 + std/src/sys/thread_local/mod.rs | 5 +- std/src/sys/thread_local/os.rs | 1 - std/src/sys_common/fs.rs | 2 +- std/src/sys_common/net.rs | 4 +- std/src/sys_common/process.rs | 8 +- std/src/sys_common/wtf8.rs | 4 +- std/src/thread/current.rs | 55 +- std/src/thread/local.rs | 33 +- std/src/thread/mod.rs | 286 +-- std/tests/env.rs | 12 +- stdarch | 2 +- unwind/Cargo.toml | 7 +- unwind/src/lib.rs | 9 +- unwind/src/libunwind.rs | 9 +- 320 files changed, 9947 insertions(+), 4966 deletions(-) create mode 100644 alloc/src/collections/btree/set/entry.rs rename alloc/{src/alloc/tests.rs => tests/alloc.rs} (93%) rename alloc/{src/ffi/c_str/tests.rs => tests/c_str2.rs} (97%) rename alloc/{src/collections/binary_heap/tests.rs => tests/collections/binary_heap.rs} (99%) create mode 100644 alloc/tests/collections/mod.rs rename alloc/{src/tests.rs => tests/misc_tests.rs} (100%) rename alloc/{src/sync/tests.rs => tests/sync.rs} (98%) create mode 100644 alloc/tests/testing/crash_test.rs create mode 100644 alloc/tests/testing/mod.rs create mode 100644 core/src/intrinsics/fallback.rs create mode 100644 core/src/num/niche_types.rs create mode 100644 core/src/unsafe_binder.rs rename std/src/sync/{ => poison}/condvar.rs (99%) rename std/src/sync/{ => poison}/condvar/tests.rs (100%) rename std/src/sync/{ => poison}/mutex.rs (89%) rename std/src/sync/{ => poison}/mutex/tests.rs (69%) rename std/src/sync/{ => poison}/once.rs (100%) rename std/src/sync/{ => poison}/once/tests.rs (100%) rename std/src/sync/{ => poison}/rwlock.rs (91%) rename std/src/sync/{ => poison}/rwlock/tests.rs (81%) create mode 100644 std/src/sys/pal/uefi/fs.rs create mode 100644 std/src/sys/pal/unix/sync/condvar.rs create mode 100644 std/src/sys/pal/unix/sync/mod.rs create mode 100644 std/src/sys/pal/unix/sync/mutex.rs diff --git a/Cargo.lock b/Cargo.lock index 55851daaf2a80..c8007dd9be046 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,21 +4,21 @@ version = 4 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "compiler_builtins", - "gimli 0.29.0", + "gimli", "rustc-std-workspace-alloc", "rustc-std-workspace-core", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", @@ -36,9 +36,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.18" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "cc" @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.138" +version = "0.1.143" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53f0ea7fff95b51f84371588f06062557e96bbe363d2b36218ddb806f3ca8611" +checksum = "c85ba2077e3eab3dd81be4ece6b7fb2ad0887c1fb813e9a45400baf75c6c7c29" dependencies = [ "cc", "rustc-std-workspace-core", @@ -111,17 +111,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "gimli" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" -dependencies = [ - "compiler_builtins", - "rustc-std-workspace-alloc", - "rustc-std-workspace-core", -] - [[package]] name = "gimli" version = "0.31.1" @@ -135,9 +124,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ "allocator-api2", "compiler_builtins", @@ -158,9 +147,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.162" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" dependencies = [ "rustc-std-workspace-core", ] @@ -177,11 +166,11 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" dependencies = [ - "adler", + "adler2", "compiler_builtins", "rustc-std-workspace-alloc", "rustc-std-workspace-core", @@ -189,9 +178,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.5" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "compiler_builtins", "memchr", @@ -235,8 +224,6 @@ name = "profiler_builtins" version = "0.0.0" dependencies = [ "cc", - "compiler_builtins", - "core", ] [[package]] @@ -405,12 +392,12 @@ dependencies = [ [[package]] name = "unwinding" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637d511437df708cee34bdec7ba2f1548d256b7acf3ff20e0a1c559f9bf3a987" +checksum = "51f06a05848f650946acef3bf525fe96612226b61f74ae23ffa4e98bfbb8ab3c" dependencies = [ "compiler_builtins", - "gimli 0.31.1", + "gimli", "rustc-std-workspace-core", ] diff --git a/Cargo.toml b/Cargo.toml index e744cfe5e0f57..e59aa518804f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ codegen-units = 10000 [profile.release.package] addr2line.debug = 0 addr2line.opt-level = "s" -adler.debug = 0 +adler2.debug = 0 gimli.debug = 0 gimli.opt-level = "s" miniz_oxide.debug = 0 diff --git a/alloc/Cargo.toml b/alloc/Cargo.toml index 3464047d4ee9e..96caac890a35c 100644 --- a/alloc/Cargo.toml +++ b/alloc/Cargo.toml @@ -10,7 +10,7 @@ edition = "2021" [dependencies] core = { path = "../core" } -compiler_builtins = { version = "=0.1.138", features = ['rustc-dep-of-std'] } +compiler_builtins = { version = "=0.1.143", features = ['rustc-dep-of-std'] } [dev-dependencies] rand = { version = "0.8.5", default-features = false, features = ["alloc"] } diff --git a/alloc/benches/lib.rs b/alloc/benches/lib.rs index c1907361f93e1..2633154318c13 100644 --- a/alloc/benches/lib.rs +++ b/alloc/benches/lib.rs @@ -4,8 +4,7 @@ #![feature(iter_next_chunk)] #![feature(repr_simd)] #![feature(slice_partition_dedup)] -#![cfg_attr(bootstrap, feature(strict_provenance))] -#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))] +#![feature(strict_provenance_lints)] #![feature(test)] #![deny(fuzzy_provenance_casts)] diff --git a/alloc/src/alloc.rs b/alloc/src/alloc.rs index 04b7315e650a2..e9b7f9856677c 100644 --- a/alloc/src/alloc.rs +++ b/alloc/src/alloc.rs @@ -10,9 +10,6 @@ use core::hint; #[cfg(not(test))] use core::ptr::{self, NonNull}; -#[cfg(test)] -mod tests; - extern "Rust" { // These are the magic symbols to call the global allocator. rustc generates // them to call `__rg_alloc` etc. if there is a `#[global_allocator]` attribute @@ -342,7 +339,7 @@ unsafe impl Allocator for Global { } } -/// The allocator for unique pointers. +/// The allocator for `Box`. #[cfg(all(not(no_global_oom_handling), not(test)))] #[lang = "exchange_malloc"] #[inline] diff --git a/alloc/src/boxed.rs b/alloc/src/boxed.rs index ee60ec0fbacbe..1b5e44a913467 100644 --- a/alloc/src/boxed.rs +++ b/alloc/src/boxed.rs @@ -191,9 +191,7 @@ use core::error::{self, Error}; use core::fmt; use core::future::Future; use core::hash::{Hash, Hasher}; -#[cfg(not(bootstrap))] -use core::marker::PointerLike; -use core::marker::{Tuple, Unsize}; +use core::marker::{PointerLike, Tuple, Unsize}; use core::mem::{self, SizedTypeProperties}; use core::ops::{ AsyncFn, AsyncFnMut, AsyncFnOnce, CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut, @@ -227,7 +225,7 @@ pub use thin::ThinBox; #[fundamental] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_insignificant_dtor] -#[cfg_attr(not(bootstrap), doc(search_unbox))] +#[doc(search_unbox)] // The declaration of the `Box` struct must be kept in sync with the // compiler or ICEs will happen. pub struct Box< @@ -235,6 +233,27 @@ pub struct Box< #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, >(Unique, A); +/// Constructs a `Box` by calling the `exchange_malloc` lang item and moving the argument into +/// the newly allocated memory. This is an intrinsic to avoid unnecessary copies. +/// +/// This is the surface syntax for `box ` expressions. +#[cfg(not(bootstrap))] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[unstable(feature = "liballoc_internals", issue = "none")] +pub fn box_new(_x: T) -> Box { + unreachable!() +} + +/// Transition function for the next bootstrap bump. +#[cfg(bootstrap)] +#[unstable(feature = "liballoc_internals", issue = "none")] +#[inline(always)] +pub fn box_new(x: T) -> Box { + #[rustc_box] + Box::new(x) +} + impl Box { /// Allocates memory on the heap and then places `x` into it. /// @@ -252,8 +271,7 @@ impl Box { #[rustc_diagnostic_item = "box_new"] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub fn new(x: T) -> Self { - #[rustc_box] - Box::new(x) + return box_new(x); } /// Constructs a new box with uninitialized contents. @@ -763,6 +781,26 @@ impl Box<[T]> { }; unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, Global).into_box(len)) } } + + /// Converts the boxed slice into a boxed array. + /// + /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub fn into_array(self) -> Option> { + if self.len() == N { + let ptr = Self::into_raw(self) as *mut [T; N]; + + // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. + let me = unsafe { Box::from_raw(ptr) }; + Some(me) + } else { + None + } + } } impl Box<[T], A> { @@ -1027,6 +1065,8 @@ impl Box { /// memory problems. For example, a double-free may occur if the /// function is called twice on the same raw pointer. /// + /// The raw pointer must point to a block of memory allocated by the global allocator. + /// /// The safety conditions are described in the [memory layout] section. /// /// # Examples @@ -1130,6 +1170,7 @@ impl Box { /// memory problems. For example, a double-free may occur if the /// function is called twice on the same raw pointer. /// + /// The raw pointer must point to a block of memory allocated by `alloc` /// /// # Examples /// @@ -1502,7 +1543,7 @@ impl Box { /// [`as_ptr`]: Self::as_ptr #[unstable(feature = "box_as_ptr", issue = "129090")] #[rustc_never_returns_null_ptr] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[inline] pub fn as_mut_ptr(b: &mut Self) -> *mut T { // This is a primitive deref, not going through `DerefMut`, and therefore not materializing @@ -1551,7 +1592,7 @@ impl Box { /// [`as_ptr`]: Self::as_ptr #[unstable(feature = "box_as_ptr", issue = "129090")] #[rustc_never_returns_null_ptr] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[inline] pub fn as_ptr(b: &Self) -> *const T { // This is a primitive deref, not going through `DerefMut`, and therefore not materializing @@ -1987,7 +2028,7 @@ impl + ?Sized, A: Allocator> Fn for Box { } } -#[unstable(feature = "async_fn_traits", issue = "none")] +#[stable(feature = "async_closure", since = "1.85.0")] impl + ?Sized, A: Allocator> AsyncFnOnce for Box { type Output = F::Output; type CallOnceFuture = F::CallOnceFuture; @@ -1997,7 +2038,7 @@ impl + ?Sized, A: Allocator> AsyncFnOnce } } -#[unstable(feature = "async_fn_traits", issue = "none")] +#[stable(feature = "async_closure", since = "1.85.0")] impl + ?Sized, A: Allocator> AsyncFnMut for Box { type CallRefFuture<'a> = F::CallRefFuture<'a> @@ -2009,7 +2050,7 @@ impl + ?Sized, A: Allocator> AsyncFnMut f } } -#[unstable(feature = "async_fn_traits", issue = "none")] +#[stable(feature = "async_closure", since = "1.85.0")] impl + ?Sized, A: Allocator> AsyncFn for Box { extern "rust-call" fn async_call(&self, args: Args) -> Self::CallRefFuture<'_> { F::async_call(self, args) @@ -2134,6 +2175,5 @@ impl Error for Box { } } -#[cfg(not(bootstrap))] #[unstable(feature = "pointer_like_trait", issue = "none")] impl PointerLike for Box {} diff --git a/alloc/src/boxed/convert.rs b/alloc/src/boxed/convert.rs index 4430fff66775c..255cefb1e78fb 100644 --- a/alloc/src/boxed/convert.rs +++ b/alloc/src/boxed/convert.rs @@ -110,7 +110,7 @@ impl From<&[T]> for Box<[T]> { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "box_from_mut_slice", since = "1.84.0")] impl From<&mut [T]> for Box<[T]> { /// Converts a `&mut [T]` into a `Box<[T]>` /// @@ -171,7 +171,7 @@ impl From<&str> for Box { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "box_from_mut_slice", since = "1.84.0")] impl From<&mut str> for Box { /// Converts a `&mut str` into a `Box` /// diff --git a/alloc/src/collections/binary_heap/mod.rs b/alloc/src/collections/binary_heap/mod.rs index 59f10b09c73fd..965fd63a52981 100644 --- a/alloc/src/collections/binary_heap/mod.rs +++ b/alloc/src/collections/binary_heap/mod.rs @@ -155,9 +155,6 @@ use crate::collections::TryReserveError; use crate::slice; use crate::vec::{self, AsVecIntoIter, Vec}; -#[cfg(test)] -mod tests; - /// A priority queue implemented with a binary heap. /// /// This will be a max-heap. @@ -452,7 +449,7 @@ impl BinaryHeap { /// /// The binary heap will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the binary heap will not allocate. + /// `capacity`. If `capacity` is zero, the binary heap will not allocate. /// /// # Examples /// @@ -486,7 +483,6 @@ impl BinaryHeap { /// heap.push(4); /// ``` #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_binary_heap_new_in", issue = "125961")] #[must_use] pub const fn new_in(alloc: A) -> BinaryHeap { BinaryHeap { data: Vec::new_in(alloc) } @@ -496,7 +492,7 @@ impl BinaryHeap { /// /// The binary heap will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the binary heap will not allocate. + /// `capacity`. If `capacity` is zero, the binary heap will not allocate. /// /// # Examples /// @@ -535,8 +531,7 @@ impl BinaryHeap { /// heap.push(1); /// heap.push(5); /// heap.push(2); - /// { - /// let mut val = heap.peek_mut().unwrap(); + /// if let Some(mut val) = heap.peek_mut() { /// *val = 0; /// } /// assert_eq!(heap.peek(), Some(&2)); diff --git a/alloc/src/collections/btree/map.rs b/alloc/src/collections/btree/map.rs index 213924d1d0203..6d305386dbfa0 100644 --- a/alloc/src/collections/btree/map.rs +++ b/alloc/src/collections/btree/map.rs @@ -308,11 +308,38 @@ impl BTreeMap { alloc: (*map.alloc).clone(), _marker: PhantomData, } - .insert(SetValZST::default()); + .insert(SetValZST); None } } } + + pub(super) fn get_or_insert_with(&mut self, q: &Q, f: F) -> &K + where + K: Borrow + Ord, + Q: Ord, + F: FnOnce(&Q) -> K, + { + let (map, dormant_map) = DormantMutRef::new(self); + let root_node = + map.root.get_or_insert_with(|| Root::new((*map.alloc).clone())).borrow_mut(); + match root_node.search_tree(q) { + Found(handle) => handle.into_kv_mut().0, + GoDown(handle) => { + let key = f(q); + assert!(*key.borrow() == *q, "new value is not equal"); + VacantEntry { + key, + handle: Some(handle), + dormant_map, + alloc: (*map.alloc).clone(), + _marker: PhantomData, + } + .insert_entry(SetValZST) + .into_key() + } + } + } } /// An iterator over the entries of a `BTreeMap`. @@ -2262,6 +2289,10 @@ impl FusedIterator for RangeMut<'_, K, V> {} #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator<(K, V)> for BTreeMap { + /// Constructs a `BTreeMap` from an iterator of key-value pairs. + /// + /// If the iterator produces any pairs with equal keys, + /// all but one of the corresponding values will be dropped. fn from_iter>(iter: T) -> BTreeMap { let mut inputs: Vec<_> = iter.into_iter().collect(); @@ -2376,7 +2407,10 @@ where #[stable(feature = "std_collections_from_array", since = "1.56.0")] impl From<[(K, V); N]> for BTreeMap { - /// Converts a `[(K, V); N]` into a `BTreeMap<(K, V)>`. + /// Converts a `[(K, V); N]` into a `BTreeMap`. + /// + /// If any entries in the array have equal keys, + /// all but one of the corresponding values will be dropped. /// /// ``` /// use std::collections::BTreeMap; diff --git a/alloc/src/collections/btree/map/entry.rs b/alloc/src/collections/btree/map/entry.rs index 75bb86916a887..ea8fa363c3805 100644 --- a/alloc/src/collections/btree/map/entry.rs +++ b/alloc/src/collections/btree/map/entry.rs @@ -269,6 +269,31 @@ impl<'a, K: Ord, V, A: Allocator + Clone> Entry<'a, K, V, A> { Vacant(entry) => Vacant(entry), } } + + /// Sets the value of the entry, and returns an `OccupiedEntry`. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_entry_insert)] + /// use std::collections::BTreeMap; + /// + /// let mut map: BTreeMap<&str, String> = BTreeMap::new(); + /// let entry = map.entry("poneyland").insert_entry("hoho".to_string()); + /// + /// assert_eq!(entry.key(), &"poneyland"); + /// ``` + #[inline] + #[unstable(feature = "btree_entry_insert", issue = "65225")] + pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, A> { + match self { + Occupied(mut entry) => { + entry.insert(value); + entry + } + Vacant(entry) => entry.insert_entry(value), + } + } } impl<'a, K: Ord, V: Default, A: Allocator + Clone> Entry<'a, K, V, A> { @@ -348,41 +373,61 @@ impl<'a, K: Ord, V, A: Allocator + Clone> VacantEntry<'a, K, V, A> { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_confusables("push", "put")] - pub fn insert(mut self, value: V) -> &'a mut V { - let out_ptr = match self.handle { + pub fn insert(self, value: V) -> &'a mut V { + self.insert_entry(value).into_mut() + } + + /// Sets the value of the entry with the `VacantEntry`'s key, + /// and returns an `OccupiedEntry`. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_entry_insert)] + /// use std::collections::BTreeMap; + /// use std::collections::btree_map::Entry; + /// + /// let mut map: BTreeMap<&str, u32> = BTreeMap::new(); + /// + /// if let Entry::Vacant(o) = map.entry("poneyland") { + /// let entry = o.insert_entry(37); + /// assert_eq!(entry.get(), &37); + /// } + /// assert_eq!(map["poneyland"], 37); + /// ``` + #[unstable(feature = "btree_entry_insert", issue = "65225")] + pub fn insert_entry(mut self, value: V) -> OccupiedEntry<'a, K, V, A> { + let handle = match self.handle { None => { // SAFETY: There is no tree yet so no reference to it exists. - let map = unsafe { self.dormant_map.awaken() }; - let mut root = NodeRef::new_leaf(self.alloc.clone()); - let val_ptr = root.borrow_mut().push(self.key, value); - map.root = Some(root.forget_type()); - map.length = 1; - val_ptr - } - Some(handle) => { - let new_handle = - handle.insert_recursing(self.key, value, self.alloc.clone(), |ins| { - drop(ins.left); - // SAFETY: Pushing a new root node doesn't invalidate - // handles to existing nodes. - let map = unsafe { self.dormant_map.reborrow() }; - let root = map.root.as_mut().unwrap(); // same as ins.left - root.push_internal_level(self.alloc).push(ins.kv.0, ins.kv.1, ins.right) - }); - - // Get the pointer to the value - let val_ptr = new_handle.into_val_mut(); - - // SAFETY: We have consumed self.handle. - let map = unsafe { self.dormant_map.awaken() }; - map.length += 1; - val_ptr + let map = unsafe { self.dormant_map.reborrow() }; + let root = map.root.insert(NodeRef::new_leaf(self.alloc.clone()).forget_type()); + // SAFETY: We *just* created the root as a leaf, and we're + // stacking the new handle on the original borrow lifetime. + unsafe { + let mut leaf = root.borrow_mut().cast_to_leaf_unchecked(); + leaf.push_with_handle(self.key, value) + } } + Some(handle) => handle.insert_recursing(self.key, value, self.alloc.clone(), |ins| { + drop(ins.left); + // SAFETY: Pushing a new root node doesn't invalidate + // handles to existing nodes. + let map = unsafe { self.dormant_map.reborrow() }; + let root = map.root.as_mut().unwrap(); // same as ins.left + root.push_internal_level(self.alloc.clone()).push(ins.kv.0, ins.kv.1, ins.right) + }), }; - // Now that we have finished growing the tree using borrowed references, - // dereference the pointer to a part of it, that we picked up along the way. - unsafe { &mut *out_ptr } + // SAFETY: modifying the length doesn't invalidate handles to existing nodes. + unsafe { self.dormant_map.reborrow().length += 1 }; + + OccupiedEntry { + handle: handle.forget_node_type(), + dormant_map: self.dormant_map, + alloc: self.alloc, + _marker: PhantomData, + } } } @@ -404,6 +449,11 @@ impl<'a, K: Ord, V, A: Allocator + Clone> OccupiedEntry<'a, K, V, A> { self.handle.reborrow().into_kv().0 } + /// Converts the entry into a reference to its key. + pub(crate) fn into_key(self) -> &'a K { + self.handle.into_kv_mut().0 + } + /// Take ownership of the key and value from the map. /// /// # Examples diff --git a/alloc/src/collections/btree/node.rs b/alloc/src/collections/btree/node.rs index 64a13bb6a0b3a..4057657632ba4 100644 --- a/alloc/src/collections/btree/node.rs +++ b/alloc/src/collections/btree/node.rs @@ -383,9 +383,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { /// Borrows a view into the keys stored in the node. pub fn keys(&self) -> &[K] { let leaf = self.into_leaf(); - unsafe { - MaybeUninit::slice_assume_init_ref(leaf.keys.get_unchecked(..usize::from(leaf.len))) - } + unsafe { leaf.keys.get_unchecked(..usize::from(leaf.len)).assume_init_ref() } } } @@ -739,7 +737,7 @@ impl NodeRef { impl<'a, K, V> NodeRef, K, V, marker::LeafOrInternal> { /// Unsafely asserts to the compiler the static information that this node is a `Leaf`. - unsafe fn cast_to_leaf_unchecked(self) -> NodeRef, K, V, marker::Leaf> { + pub unsafe fn cast_to_leaf_unchecked(self) -> NodeRef, K, V, marker::Leaf> { debug_assert!(self.height == 0); NodeRef { height: self.height, node: self.node, _marker: PhantomData } } diff --git a/alloc/src/collections/btree/set.rs b/alloc/src/collections/btree/set.rs index 8daee6030c270..9660023d6945e 100644 --- a/alloc/src/collections/btree/set.rs +++ b/alloc/src/collections/btree/set.rs @@ -7,12 +7,17 @@ use core::iter::{FusedIterator, Peekable}; use core::mem::ManuallyDrop; use core::ops::{BitAnd, BitOr, BitXor, Bound, RangeBounds, Sub}; -use super::map::{BTreeMap, Keys}; +use super::map::{self, BTreeMap, Keys}; use super::merge_iter::MergeIterInner; use super::set_val::SetValZST; use crate::alloc::{Allocator, Global}; use crate::vec::Vec; +mod entry; + +#[unstable(feature = "btree_set_entry", issue = "133549")] +pub use self::entry::{Entry, OccupiedEntry, VacantEntry}; + /// An ordered set based on a B-Tree. /// /// See [`BTreeMap`]'s documentation for a detailed discussion of this collection's performance @@ -928,6 +933,109 @@ impl BTreeSet { self.map.replace(value) } + /// Inserts the given `value` into the set if it is not present, then + /// returns a reference to the value in the set. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::BTreeSet; + /// + /// let mut set = BTreeSet::from([1, 2, 3]); + /// assert_eq!(set.len(), 3); + /// assert_eq!(set.get_or_insert(2), &2); + /// assert_eq!(set.get_or_insert(100), &100); + /// assert_eq!(set.len(), 4); // 100 was inserted + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "133549")] + pub fn get_or_insert(&mut self, value: T) -> &T + where + T: Ord, + { + self.map.entry(value).insert_entry(SetValZST).into_key() + } + + /// Inserts a value computed from `f` into the set if the given `value` is + /// not present, then returns a reference to the value in the set. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::BTreeSet; + /// + /// let mut set: BTreeSet = ["cat", "dog", "horse"] + /// .iter().map(|&pet| pet.to_owned()).collect(); + /// + /// assert_eq!(set.len(), 3); + /// for &pet in &["cat", "dog", "fish"] { + /// let value = set.get_or_insert_with(pet, str::to_owned); + /// assert_eq!(value, pet); + /// } + /// assert_eq!(set.len(), 4); // a new "fish" was inserted + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "133549")] + pub fn get_or_insert_with(&mut self, value: &Q, f: F) -> &T + where + T: Borrow + Ord, + Q: Ord, + F: FnOnce(&Q) -> T, + { + self.map.get_or_insert_with(value, f) + } + + /// Gets the given value's corresponding entry in the set for in-place manipulation. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::BTreeSet; + /// use std::collections::btree_set::Entry::*; + /// + /// let mut singles = BTreeSet::new(); + /// let mut dupes = BTreeSet::new(); + /// + /// for ch in "a short treatise on fungi".chars() { + /// if let Vacant(dupe_entry) = dupes.entry(ch) { + /// // We haven't already seen a duplicate, so + /// // check if we've at least seen it once. + /// match singles.entry(ch) { + /// Vacant(single_entry) => { + /// // We found a new character for the first time. + /// single_entry.insert() + /// } + /// Occupied(single_entry) => { + /// // We've already seen this once, "move" it to dupes. + /// single_entry.remove(); + /// dupe_entry.insert(); + /// } + /// } + /// } + /// } + /// + /// assert!(!singles.contains(&'t') && dupes.contains(&'t')); + /// assert!(singles.contains(&'u') && !dupes.contains(&'u')); + /// assert!(!singles.contains(&'v') && !dupes.contains(&'v')); + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "133549")] + pub fn entry(&mut self, value: T) -> Entry<'_, T, A> + where + T: Ord, + { + match self.map.entry(value) { + map::Entry::Occupied(entry) => Entry::Occupied(OccupiedEntry { inner: entry }), + map::Entry::Vacant(entry) => Entry::Vacant(VacantEntry { inner: entry }), + } + } + /// If the set contains an element equal to the value, removes it from the /// set and drops it. Returns whether such an element was present. /// @@ -1383,6 +1491,11 @@ impl BTreeSet { impl From<[T; N]> for BTreeSet { /// Converts a `[T; N]` into a `BTreeSet`. /// + /// If the array contains any equal values, + /// all but one will be dropped. + /// + /// # Examples + /// /// ``` /// use std::collections::BTreeSet; /// diff --git a/alloc/src/collections/btree/set/entry.rs b/alloc/src/collections/btree/set/entry.rs new file mode 100644 index 0000000000000..a60d22f9ece71 --- /dev/null +++ b/alloc/src/collections/btree/set/entry.rs @@ -0,0 +1,388 @@ +use core::fmt::{self, Debug}; + +use Entry::*; + +use super::{SetValZST, map}; +use crate::alloc::{Allocator, Global}; + +/// A view into a single entry in a set, which may either be vacant or occupied. +/// +/// This `enum` is constructed from the [`entry`] method on [`BTreeSet`]. +/// +/// [`BTreeSet`]: super::BTreeSet +/// [`entry`]: super::BTreeSet::entry +/// +/// # Examples +/// +/// ``` +/// #![feature(btree_set_entry)] +/// +/// use std::collections::btree_set::BTreeSet; +/// +/// let mut set = BTreeSet::new(); +/// set.extend(["a", "b", "c"]); +/// assert_eq!(set.len(), 3); +/// +/// // Existing value (insert) +/// let entry = set.entry("a"); +/// let _raw_o = entry.insert(); +/// assert_eq!(set.len(), 3); +/// // Nonexistent value (insert) +/// set.entry("d").insert(); +/// +/// // Existing value (or_insert) +/// set.entry("b").or_insert(); +/// // Nonexistent value (or_insert) +/// set.entry("e").or_insert(); +/// +/// println!("Our BTreeSet: {:?}", set); +/// assert!(set.iter().eq(&["a", "b", "c", "d", "e"])); +/// ``` +#[unstable(feature = "btree_set_entry", issue = "133549")] +pub enum Entry< + 'a, + T, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global, +> { + /// An occupied entry. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::btree_set::{Entry, BTreeSet}; + /// + /// let mut set = BTreeSet::from(["a", "b"]); + /// + /// match set.entry("a") { + /// Entry::Vacant(_) => unreachable!(), + /// Entry::Occupied(_) => { } + /// } + /// ``` + #[unstable(feature = "btree_set_entry", issue = "133549")] + Occupied(OccupiedEntry<'a, T, A>), + + /// A vacant entry. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::btree_set::{Entry, BTreeSet}; + /// + /// let mut set = BTreeSet::new(); + /// + /// match set.entry("a") { + /// Entry::Occupied(_) => unreachable!(), + /// Entry::Vacant(_) => { } + /// } + /// ``` + #[unstable(feature = "btree_set_entry", issue = "133549")] + Vacant(VacantEntry<'a, T, A>), +} + +#[unstable(feature = "btree_set_entry", issue = "133549")] +impl Debug for Entry<'_, T, A> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(), + Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(), + } + } +} + +/// A view into an occupied entry in a `BTreeSet`. +/// It is part of the [`Entry`] enum. +/// +/// # Examples +/// +/// ``` +/// #![feature(btree_set_entry)] +/// +/// use std::collections::btree_set::{Entry, BTreeSet}; +/// +/// let mut set = BTreeSet::new(); +/// set.extend(["a", "b", "c"]); +/// +/// let _entry_o = set.entry("a").insert(); +/// assert_eq!(set.len(), 3); +/// +/// // Existing key +/// match set.entry("a") { +/// Entry::Vacant(_) => unreachable!(), +/// Entry::Occupied(view) => { +/// assert_eq!(view.get(), &"a"); +/// } +/// } +/// +/// assert_eq!(set.len(), 3); +/// +/// // Existing key (take) +/// match set.entry("c") { +/// Entry::Vacant(_) => unreachable!(), +/// Entry::Occupied(view) => { +/// assert_eq!(view.remove(), "c"); +/// } +/// } +/// assert_eq!(set.get(&"c"), None); +/// assert_eq!(set.len(), 2); +/// ``` +#[unstable(feature = "btree_set_entry", issue = "133549")] +pub struct OccupiedEntry< + 'a, + T, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global, +> { + pub(super) inner: map::OccupiedEntry<'a, T, SetValZST, A>, +} + +#[unstable(feature = "btree_set_entry", issue = "133549")] +impl Debug for OccupiedEntry<'_, T, A> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("OccupiedEntry").field("value", self.get()).finish() + } +} + +/// A view into a vacant entry in a `BTreeSet`. +/// It is part of the [`Entry`] enum. +/// +/// # Examples +/// +/// ``` +/// #![feature(btree_set_entry)] +/// +/// use std::collections::btree_set::{Entry, BTreeSet}; +/// +/// let mut set = BTreeSet::<&str>::new(); +/// +/// let entry_v = match set.entry("a") { +/// Entry::Vacant(view) => view, +/// Entry::Occupied(_) => unreachable!(), +/// }; +/// entry_v.insert(); +/// assert!(set.contains("a") && set.len() == 1); +/// +/// // Nonexistent key (insert) +/// match set.entry("b") { +/// Entry::Vacant(view) => view.insert(), +/// Entry::Occupied(_) => unreachable!(), +/// } +/// assert!(set.contains("b") && set.len() == 2); +/// ``` +#[unstable(feature = "btree_set_entry", issue = "133549")] +pub struct VacantEntry< + 'a, + T, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global, +> { + pub(super) inner: map::VacantEntry<'a, T, SetValZST, A>, +} + +#[unstable(feature = "btree_set_entry", issue = "133549")] +impl Debug for VacantEntry<'_, T, A> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("VacantEntry").field(self.get()).finish() + } +} + +impl<'a, T: Ord, A: Allocator + Clone> Entry<'a, T, A> { + /// Sets the value of the entry, and returns an `OccupiedEntry`. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::BTreeSet; + /// + /// let mut set = BTreeSet::new(); + /// let entry = set.entry("horseyland").insert(); + /// + /// assert_eq!(entry.get(), &"horseyland"); + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "133549")] + pub fn insert(self) -> OccupiedEntry<'a, T, A> { + match self { + Occupied(entry) => entry, + Vacant(entry) => entry.insert_entry(), + } + } + + /// Ensures a value is in the entry by inserting if it was vacant. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::BTreeSet; + /// + /// let mut set = BTreeSet::new(); + /// + /// // nonexistent key + /// set.entry("poneyland").or_insert(); + /// assert!(set.contains("poneyland")); + /// + /// // existing key + /// set.entry("poneyland").or_insert(); + /// assert!(set.contains("poneyland")); + /// assert_eq!(set.len(), 1); + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "133549")] + pub fn or_insert(self) { + if let Vacant(entry) = self { + entry.insert(); + } + } + + /// Returns a reference to this entry's value. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::BTreeSet; + /// + /// let mut set = BTreeSet::new(); + /// set.entry("poneyland").or_insert(); + /// + /// // existing key + /// assert_eq!(set.entry("poneyland").get(), &"poneyland"); + /// // nonexistent key + /// assert_eq!(set.entry("horseland").get(), &"horseland"); + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "133549")] + pub fn get(&self) -> &T { + match *self { + Occupied(ref entry) => entry.get(), + Vacant(ref entry) => entry.get(), + } + } +} + +impl<'a, T: Ord, A: Allocator + Clone> OccupiedEntry<'a, T, A> { + /// Gets a reference to the value in the entry. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::btree_set::{Entry, BTreeSet}; + /// + /// let mut set = BTreeSet::new(); + /// set.entry("poneyland").or_insert(); + /// + /// match set.entry("poneyland") { + /// Entry::Vacant(_) => panic!(), + /// Entry::Occupied(entry) => assert_eq!(entry.get(), &"poneyland"), + /// } + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "133549")] + pub fn get(&self) -> &T { + self.inner.key() + } + + /// Takes the value out of the entry, and returns it. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::BTreeSet; + /// use std::collections::btree_set::Entry; + /// + /// let mut set = BTreeSet::new(); + /// set.entry("poneyland").or_insert(); + /// + /// if let Entry::Occupied(o) = set.entry("poneyland") { + /// assert_eq!(o.remove(), "poneyland"); + /// } + /// + /// assert_eq!(set.contains("poneyland"), false); + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "133549")] + pub fn remove(self) -> T { + self.inner.remove_entry().0 + } +} + +impl<'a, T: Ord, A: Allocator + Clone> VacantEntry<'a, T, A> { + /// Gets a reference to the value that would be used when inserting + /// through the `VacantEntry`. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::BTreeSet; + /// + /// let mut set = BTreeSet::new(); + /// assert_eq!(set.entry("poneyland").get(), &"poneyland"); + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "133549")] + pub fn get(&self) -> &T { + self.inner.key() + } + + /// Take ownership of the value. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::btree_set::{Entry, BTreeSet}; + /// + /// let mut set = BTreeSet::new(); + /// + /// match set.entry("poneyland") { + /// Entry::Occupied(_) => panic!(), + /// Entry::Vacant(v) => assert_eq!(v.into_value(), "poneyland"), + /// } + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "133549")] + pub fn into_value(self) -> T { + self.inner.into_key() + } + + /// Sets the value of the entry with the VacantEntry's value. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::BTreeSet; + /// use std::collections::btree_set::Entry; + /// + /// let mut set = BTreeSet::new(); + /// + /// if let Entry::Vacant(o) = set.entry("poneyland") { + /// o.insert(); + /// } + /// assert!(set.contains("poneyland")); + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "133549")] + pub fn insert(self) { + self.inner.insert(SetValZST); + } + + #[inline] + fn insert_entry(self) -> OccupiedEntry<'a, T, A> { + OccupiedEntry { inner: self.inner.insert_entry(SetValZST) } + } +} diff --git a/alloc/src/collections/linked_list.rs b/alloc/src/collections/linked_list.rs index ca0ea1ec8b2ba..13168b7a39fe4 100644 --- a/alloc/src/collections/linked_list.rs +++ b/alloc/src/collections/linked_list.rs @@ -1939,9 +1939,7 @@ pub struct ExtractIf< T: 'a, F: 'a, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, -> where - F: FnMut(&mut T) -> bool, -{ +> { list: &'a mut LinkedList, it: Option>>, pred: F, @@ -1979,10 +1977,7 @@ where } #[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] -impl fmt::Debug for ExtractIf<'_, T, F> -where - F: FnMut(&mut T) -> bool, -{ +impl fmt::Debug for ExtractIf<'_, T, F> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("ExtractIf").field(&self.list).finish() } diff --git a/alloc/src/collections/vec_deque/mod.rs b/alloc/src/collections/vec_deque/mod.rs index cf51a84bb6f24..0b6a55297e1ab 100644 --- a/alloc/src/collections/vec_deque/mod.rs +++ b/alloc/src/collections/vec_deque/mod.rs @@ -1869,7 +1869,7 @@ impl VecDeque { /// /// # Panics /// - /// Panics if `index` is greater than deque's length + /// Panics if `index` is strictly greater than deque's length /// /// # Examples /// @@ -1884,6 +1884,9 @@ impl VecDeque { /// /// vec_deque.insert(1, 'd'); /// assert_eq!(vec_deque, &['a', 'd', 'b', 'c']); + /// + /// vec_deque.insert(4, 'e'); + /// assert_eq!(vec_deque, &['a', 'd', 'b', 'c', 'e']); /// ``` #[stable(feature = "deque_extras_15", since = "1.5.0")] #[track_caller] @@ -1928,13 +1931,13 @@ impl VecDeque { /// use std::collections::VecDeque; /// /// let mut buf = VecDeque::new(); - /// buf.push_back(1); - /// buf.push_back(2); - /// buf.push_back(3); - /// assert_eq!(buf, [1, 2, 3]); + /// buf.push_back('a'); + /// buf.push_back('b'); + /// buf.push_back('c'); + /// assert_eq!(buf, ['a', 'b', 'c']); /// - /// assert_eq!(buf.remove(1), Some(2)); - /// assert_eq!(buf, [1, 3]); + /// assert_eq!(buf.remove(1), Some('b')); + /// assert_eq!(buf, ['a', 'c']); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_confusables("delete", "take")] @@ -1982,10 +1985,10 @@ impl VecDeque { /// ``` /// use std::collections::VecDeque; /// - /// let mut buf: VecDeque<_> = [1, 2, 3].into(); + /// let mut buf: VecDeque<_> = ['a', 'b', 'c'].into(); /// let buf2 = buf.split_off(1); - /// assert_eq!(buf, [1]); - /// assert_eq!(buf2, [2, 3]); + /// assert_eq!(buf, ['a']); + /// assert_eq!(buf2, ['b', 'c']); /// ``` #[inline] #[must_use = "use `.truncate()` if you don't need the other half"] diff --git a/alloc/src/ffi/c_str.rs b/alloc/src/ffi/c_str.rs index d91682b796e4f..c7d6d8a55c2e3 100644 --- a/alloc/src/ffi/c_str.rs +++ b/alloc/src/ffi/c_str.rs @@ -1,8 +1,5 @@ //! [`CString`] and its related types. -#[cfg(test)] -mod tests; - use core::borrow::Borrow; use core::ffi::{CStr, c_char}; use core::num::NonZero; @@ -384,7 +381,7 @@ impl CString { /// fn some_extern_function(s: *mut c_char); /// } /// - /// let c_string = CString::new("Hello!").expect("CString::new failed"); + /// let c_string = CString::from(c"Hello!"); /// let raw = c_string.into_raw(); /// unsafe { /// some_extern_function(raw); @@ -429,7 +426,7 @@ impl CString { /// ``` /// use std::ffi::CString; /// - /// let c_string = CString::new("foo").expect("CString::new failed"); + /// let c_string = CString::from(c"foo"); /// /// let ptr = c_string.into_raw(); /// @@ -487,7 +484,7 @@ impl CString { /// ``` /// use std::ffi::CString; /// - /// let c_string = CString::new("foo").expect("CString::new failed"); + /// let c_string = CString::from(c"foo"); /// let bytes = c_string.into_bytes(); /// assert_eq!(bytes, vec![b'f', b'o', b'o']); /// ``` @@ -508,7 +505,7 @@ impl CString { /// ``` /// use std::ffi::CString; /// - /// let c_string = CString::new("foo").expect("CString::new failed"); + /// let c_string = CString::from(c"foo"); /// let bytes = c_string.into_bytes_with_nul(); /// assert_eq!(bytes, vec![b'f', b'o', b'o', b'\0']); /// ``` @@ -530,7 +527,7 @@ impl CString { /// ``` /// use std::ffi::CString; /// - /// let c_string = CString::new("foo").expect("CString::new failed"); + /// let c_string = CString::from(c"foo"); /// let bytes = c_string.as_bytes(); /// assert_eq!(bytes, &[b'f', b'o', b'o']); /// ``` @@ -550,7 +547,7 @@ impl CString { /// ``` /// use std::ffi::CString; /// - /// let c_string = CString::new("foo").expect("CString::new failed"); + /// let c_string = CString::from(c"foo"); /// let bytes = c_string.as_bytes_with_nul(); /// assert_eq!(bytes, &[b'f', b'o', b'o', b'\0']); /// ``` @@ -568,7 +565,7 @@ impl CString { /// ``` /// use std::ffi::{CString, CStr}; /// - /// let c_string = CString::new(b"foo".to_vec()).expect("CString::new failed"); + /// let c_string = CString::from(c"foo"); /// let cstr = c_string.as_c_str(); /// assert_eq!(cstr, /// CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed")); @@ -586,12 +583,9 @@ impl CString { /// # Examples /// /// ``` - /// use std::ffi::{CString, CStr}; - /// - /// let c_string = CString::new(b"foo".to_vec()).expect("CString::new failed"); + /// let c_string = c"foo".to_owned(); /// let boxed = c_string.into_boxed_c_str(); - /// assert_eq!(&*boxed, - /// CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed")); + /// assert_eq!(boxed.to_bytes_with_nul(), b"foo\0"); /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "into_boxed_c_str", since = "1.20.0")] @@ -658,7 +652,7 @@ impl CString { /// assert_eq!( /// CString::from_vec_with_nul(b"abc\0".to_vec()) /// .expect("CString::from_vec_with_nul failed"), - /// CString::new(b"abc".to_vec()).expect("CString::new failed") + /// c"abc".to_owned() /// ); /// ``` /// @@ -773,7 +767,7 @@ impl From<&CStr> for Box { } #[cfg(not(test))] -#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "box_from_mut_slice", since = "1.84.0")] impl From<&mut CStr> for Box { /// Converts a `&mut CStr` into a `Box`, /// by copying the contents into a newly allocated [`Box`]. @@ -921,7 +915,7 @@ impl From<&CStr> for Arc { } #[cfg(target_has_atomic = "ptr")] -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut CStr> for Arc { /// Converts a `&mut CStr` into a `Arc`, /// by copying the contents into a newly allocated [`Arc`]. @@ -953,7 +947,7 @@ impl From<&CStr> for Rc { } } -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut CStr> for Rc { /// Converts a `&mut CStr` into a `Rc`, /// by copying the contents into a newly allocated [`Rc`]. @@ -1168,11 +1162,12 @@ impl CStr { /// # Examples /// /// ``` - /// use std::ffi::CString; + /// use std::ffi::{CStr, CString}; /// - /// let c_string = CString::new(b"foo".to_vec()).expect("CString::new failed"); - /// let boxed = c_string.into_boxed_c_str(); - /// assert_eq!(boxed.into_c_string(), CString::new("foo").expect("CString::new failed")); + /// let boxed: Box = Box::from(c"foo"); + /// let c_string: CString = c"foo".to_owned(); + /// + /// assert_eq!(boxed.into_c_string(), c_string); /// ``` #[rustc_allow_incoherent_impl] #[must_use = "`self` will be dropped if the result is not used"] diff --git a/alloc/src/ffi/mod.rs b/alloc/src/ffi/mod.rs index 4f9dc40a3cfc9..695d7ad07cf76 100644 --- a/alloc/src/ffi/mod.rs +++ b/alloc/src/ffi/mod.rs @@ -83,7 +83,7 @@ #[doc(inline)] #[stable(feature = "alloc_c_string", since = "1.64.0")] pub use self::c_str::CString; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "alloc_c_string", since = "1.64.0")] pub use self::c_str::{FromVecWithNulError, IntoStringError, NulError}; diff --git a/alloc/src/fmt.rs b/alloc/src/fmt.rs index 695dddb25eeb4..e40de13f3d4a9 100644 --- a/alloc/src/fmt.rs +++ b/alloc/src/fmt.rs @@ -596,6 +596,8 @@ pub use core::fmt::{Arguments, write}; pub use core::fmt::{Binary, Octal}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::fmt::{Debug, Display}; +#[unstable(feature = "formatting_options", issue = "118117")] +pub use core::fmt::{DebugAsHex, FormattingOptions, Sign}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::fmt::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple}; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/alloc/src/lib.rs b/alloc/src/lib.rs index 041ff37897f05..b4f08debc932a 100644 --- a/alloc/src/lib.rs +++ b/alloc/src/lib.rs @@ -91,8 +91,6 @@ // // Library features: // tidy-alphabetical-start -#![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))] -#![cfg_attr(not(no_global_oom_handling), feature(const_btree_len))] #![cfg_attr(test, feature(str_as_str))] #![feature(alloc_layout_extra)] #![feature(allocator_api)] @@ -101,19 +99,13 @@ #![feature(array_windows)] #![feature(ascii_char)] #![feature(assert_matches)] -#![feature(async_closure)] #![feature(async_fn_traits)] #![feature(async_iterator)] #![feature(box_uninit_write)] #![feature(clone_to_uninit)] #![feature(coerce_unsized)] -#![feature(const_align_of_val)] -#![feature(const_box)] #![feature(const_eval_select)] #![feature(const_heap)] -#![feature(const_maybe_uninit_write)] -#![feature(const_size_of_val)] -#![feature(const_vec_string_slice)] #![feature(core_intrinsics)] #![feature(deprecated_suggestion)] #![feature(deref_pure_trait)] @@ -124,6 +116,7 @@ #![feature(extend_one_unchecked)] #![feature(fmt_internals)] #![feature(fn_traits)] +#![feature(formatting_options)] #![feature(hasher_prefixfree_extras)] #![feature(inplace_iteration)] #![feature(iter_advance_by)] @@ -133,6 +126,7 @@ #![feature(local_waker)] #![feature(maybe_uninit_slice)] #![feature(maybe_uninit_uninit_array_transpose)] +#![feature(nonnull_provenance)] #![feature(panic_internals)] #![feature(pattern)] #![feature(pin_coerce_unsized_trait)] @@ -149,6 +143,7 @@ #![feature(slice_range)] #![feature(std_internals)] #![feature(str_internals)] +#![feature(temporary_niche_types)] #![feature(trusted_fused)] #![feature(trusted_len)] #![feature(trusted_random_access)] @@ -163,8 +158,6 @@ // // Language features: // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(strict_provenance))] -#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))] #![cfg_attr(not(test), feature(coroutine_trait))] #![cfg_attr(test, feature(panic_update_hook))] #![cfg_attr(test, feature(test))] @@ -172,11 +165,11 @@ #![feature(allow_internal_unstable)] #![feature(cfg_sanitize)] #![feature(const_precise_live_drops)] -#![feature(const_try)] #![feature(decl_macro)] #![feature(dropck_eyepatch)] #![feature(fundamental)] #![feature(hashmap_internals)] +#![feature(intrinsics)] #![feature(lang_items)] #![feature(min_specialization)] #![feature(multiple_supertrait_upcastable)] @@ -188,6 +181,7 @@ #![feature(slice_internals)] #![feature(staged_api)] #![feature(stmt_expr_attributes)] +#![feature(strict_provenance_lints)] #![feature(unboxed_closures)] #![feature(unsized_fn_params)] #![feature(with_negative_coherence)] @@ -247,8 +241,6 @@ pub mod string; pub mod sync; #[cfg(all(not(no_global_oom_handling), not(no_rc), not(no_sync)))] pub mod task; -#[cfg(test)] -mod tests; pub mod vec; #[doc(hidden)] diff --git a/alloc/src/macros.rs b/alloc/src/macros.rs index 8c6a367869ce0..c000fd6f4efa7 100644 --- a/alloc/src/macros.rs +++ b/alloc/src/macros.rs @@ -48,10 +48,9 @@ macro_rules! vec { ); ($($x:expr),+ $(,)?) => ( <[_]>::into_vec( - // This rustc_box is not required, but it produces a dramatic improvement in compile - // time when constructing arrays with many elements. - #[rustc_box] - $crate::boxed::Box::new([$($x),+]) + // Using the intrinsic produces a dramatic improvement in stack usage for + // unoptimized programs using this code path to construct large Vecs. + $crate::boxed::box_new([$($x),+]) ) ); } diff --git a/alloc/src/raw_vec.rs b/alloc/src/raw_vec.rs index 85a9120c7e255..ad86bf4bf072f 100644 --- a/alloc/src/raw_vec.rs +++ b/alloc/src/raw_vec.rs @@ -33,21 +33,15 @@ enum AllocInit { Zeroed, } -#[repr(transparent)] -#[cfg_attr(target_pointer_width = "16", rustc_layout_scalar_valid_range_end(0x7fff))] -#[cfg_attr(target_pointer_width = "32", rustc_layout_scalar_valid_range_end(0x7fff_ffff))] -#[cfg_attr(target_pointer_width = "64", rustc_layout_scalar_valid_range_end(0x7fff_ffff_ffff_ffff))] -struct Cap(usize); +type Cap = core::num::niche_types::UsizeNoHighBit; -impl Cap { - const ZERO: Cap = unsafe { Cap(0) }; +const ZERO_CAP: Cap = unsafe { Cap::new_unchecked(0) }; - /// `Cap(cap)`, except if `T` is a ZST then `Cap::ZERO`. - /// - /// # Safety: cap must be <= `isize::MAX`. - unsafe fn new(cap: usize) -> Self { - if T::IS_ZST { Cap::ZERO } else { unsafe { Self(cap) } } - } +/// `Cap(cap)`, except if `T` is a ZST then `Cap::ZERO`. +/// +/// # Safety: cap must be <= `isize::MAX`. +unsafe fn new_cap(cap: usize) -> Cap { + if T::IS_ZST { ZERO_CAP } else { unsafe { Cap::new_unchecked(cap) } } } /// A low-level utility for more ergonomically allocating, reallocating, and deallocating @@ -103,7 +97,6 @@ impl RawVec { /// `RawVec` with capacity `usize::MAX`. Useful for implementing /// delayed allocation. #[must_use] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "raw_vec_internals_const", since = "1.81"))] pub const fn new() -> Self { Self::new_in(Global) } @@ -179,7 +172,6 @@ impl RawVec { /// Like `new`, but parameterized over the choice of allocator for /// the returned `RawVec`. #[inline] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "raw_vec_internals_const", since = "1.81"))] pub const fn new_in(alloc: A) -> Self { Self { inner: RawVecInner::new_in(alloc, align_of::()), _marker: PhantomData } } @@ -259,7 +251,7 @@ impl RawVec { // SAFETY: Precondition passed to the caller unsafe { let ptr = ptr.cast(); - let capacity = Cap::new::(capacity); + let capacity = new_cap::(capacity); Self { inner: RawVecInner::from_raw_parts_in(ptr, capacity, alloc), _marker: PhantomData, @@ -277,7 +269,7 @@ impl RawVec { // SAFETY: Precondition passed to the caller unsafe { let ptr = ptr.cast(); - let capacity = Cap::new::(capacity); + let capacity = new_cap::(capacity); Self { inner: RawVecInner::from_nonnull_in(ptr, capacity, alloc), _marker: PhantomData } } } @@ -409,11 +401,10 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for RawVec { impl RawVecInner { #[inline] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "raw_vec_internals_const", since = "1.81"))] const fn new_in(alloc: A, align: usize) -> Self { let ptr = unsafe { core::mem::transmute(align) }; // `cap: 0` means "unallocated". zero-sized types are ignored. - Self { ptr, cap: Cap::ZERO, alloc } + Self { ptr, cap: ZERO_CAP, alloc } } #[cfg(not(no_global_oom_handling))] @@ -423,7 +414,7 @@ impl RawVecInner { match Self::try_allocate_in(capacity, AllocInit::Uninitialized, alloc, elem_layout) { Ok(this) => { unsafe { - // Make it more obvious that a subsquent Vec::reserve(capacity) will not allocate. + // Make it more obvious that a subsequent Vec::reserve(capacity) will not allocate. hint::assert_unchecked(!this.needs_to_grow(0, capacity, elem_layout)); } this @@ -486,7 +477,11 @@ impl RawVecInner { // Allocators currently return a `NonNull<[u8]>` whose length // matches the size requested. If that ever changes, the capacity // here should change to `ptr.len() / mem::size_of::()`. - Ok(Self { ptr: Unique::from(ptr.cast()), cap: unsafe { Cap(capacity) }, alloc }) + Ok(Self { + ptr: Unique::from(ptr.cast()), + cap: unsafe { Cap::new_unchecked(capacity) }, + alloc, + }) } #[inline] @@ -511,7 +506,7 @@ impl RawVecInner { #[inline] const fn capacity(&self, elem_size: usize) -> usize { - if elem_size == 0 { usize::MAX } else { self.cap.0 } + if elem_size == 0 { usize::MAX } else { self.cap.as_inner() } } #[inline] @@ -521,7 +516,7 @@ impl RawVecInner { #[inline] fn current_memory(&self, elem_layout: Layout) -> Option<(NonNull, Layout)> { - if elem_layout.size() == 0 || self.cap.0 == 0 { + if elem_layout.size() == 0 || self.cap.as_inner() == 0 { None } else { // We could use Layout::array here which ensures the absence of isize and usize overflows @@ -529,7 +524,7 @@ impl RawVecInner { // has already been allocated so we know it can't overflow and currently Rust does not // support such types. So we can do better by skipping some checks and avoid an unwrap. unsafe { - let alloc_size = elem_layout.size().unchecked_mul(self.cap.0); + let alloc_size = elem_layout.size().unchecked_mul(self.cap.as_inner()); let layout = Layout::from_size_align_unchecked(alloc_size, elem_layout.align()); Some((self.ptr.into(), layout)) } @@ -565,7 +560,7 @@ impl RawVecInner { #[inline] #[track_caller] fn grow_one(&mut self, elem_layout: Layout) { - if let Err(err) = self.grow_amortized(self.cap.0, 1, elem_layout) { + if let Err(err) = self.grow_amortized(self.cap.as_inner(), 1, elem_layout) { handle_error(err); } } @@ -630,7 +625,7 @@ impl RawVecInner { // the size requested. If that ever changes, the capacity here should // change to `ptr.len() / mem::size_of::()`. self.ptr = Unique::from(ptr.cast()); - self.cap = unsafe { Cap(cap) }; + self.cap = unsafe { Cap::new_unchecked(cap) }; } fn grow_amortized( @@ -653,7 +648,7 @@ impl RawVecInner { // This guarantees exponential growth. The doubling cannot overflow // because `cap <= isize::MAX` and the type of `cap` is `usize`. - let cap = cmp::max(self.cap.0 * 2, required_cap); + let cap = cmp::max(self.cap.as_inner() * 2, required_cap); let cap = cmp::max(min_non_zero_cap(elem_layout.size()), cap); let new_layout = layout_array(cap, elem_layout)?; @@ -722,7 +717,7 @@ impl RawVecInner { unsafe { self.alloc.deallocate(ptr, layout) }; self.ptr = unsafe { Unique::new_unchecked(ptr::without_provenance_mut(elem_layout.align())) }; - self.cap = Cap::ZERO; + self.cap = ZERO_CAP; } else { let ptr = unsafe { // Layout cannot overflow here because it would have @@ -757,7 +752,9 @@ impl RawVecInner { } } -#[inline(never)] +// not marked inline(never) since we want optimizers to be able to observe the specifics of this +// function, see tests/codegen/vec-reserve-extend.rs. +#[cold] fn finish_grow( new_layout: Layout, current_memory: Option<(NonNull, Layout)>, diff --git a/alloc/src/rc.rs b/alloc/src/rc.rs index 3a9bd1b5bf119..ae3318b839dd7 100644 --- a/alloc/src/rc.rs +++ b/alloc/src/rc.rs @@ -252,6 +252,7 @@ use core::intrinsics::abort; use core::iter; use core::marker::{PhantomData, Unsize}; use core::mem::{self, ManuallyDrop, align_of_val_raw}; +use core::num::NonZeroUsize; use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, LegacyReceiver}; use core::panic::{RefUnwindSafe, UnwindSafe}; #[cfg(not(no_global_oom_handling))] @@ -307,7 +308,7 @@ fn rc_inner_layout_for_value_layout(layout: Layout) -> Layout { /// `value.get_mut()`. This avoids conflicts with methods of the inner type `T`. /// /// [get_mut]: Rc::get_mut -#[cfg_attr(not(bootstrap), doc(search_unbox))] +#[doc(search_unbox)] #[cfg_attr(not(test), rustc_diagnostic_item = "Rc")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_insignificant_dtor] @@ -795,7 +796,7 @@ impl Rc { let uninit_ptr: NonNull<_> = (unsafe { &mut *uninit_raw_ptr }).into(); let init_ptr: NonNull> = uninit_ptr.cast(); - let weak = Weak { ptr: init_ptr, alloc: alloc }; + let weak = Weak { ptr: init_ptr, alloc }; // It's important we don't give up ownership of the weak pointer, or // else the memory might be freed by the time `data_fn` returns. If @@ -1084,6 +1085,26 @@ impl Rc<[T]> { )) } } + + /// Converts the reference-counted slice into a reference-counted array. + /// + /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub fn into_array(self) -> Option> { + if self.len() == N { + let ptr = Self::into_raw(self) as *const [T; N]; + + // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. + let me = unsafe { Rc::from_raw(ptr) }; + Some(me) + } else { + None + } + } } impl Rc<[T], A> { @@ -1769,7 +1790,7 @@ impl Rc { /// let x: Rc<&str> = Rc::new("Hello, world!"); /// { /// let s = String::from("Oh, no!"); - /// let mut y: Rc<&str> = x.clone().into(); + /// let mut y: Rc<&str> = x.clone(); /// unsafe { /// // this is Undefined Behavior, because x's inner type /// // is &'long str, not &'short str @@ -2232,12 +2253,20 @@ impl Deref for Rc { #[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] unsafe impl PinCoerceUnsized for Rc {} +//#[unstable(feature = "unique_rc_arc", issue = "112566")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +unsafe impl PinCoerceUnsized for UniqueRc {} + #[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] unsafe impl PinCoerceUnsized for Weak {} #[unstable(feature = "deref_pure_trait", issue = "87121")] unsafe impl DerefPure for Rc {} +//#[unstable(feature = "unique_rc_arc", issue = "112566")] +#[unstable(feature = "deref_pure_trait", issue = "87121")] +unsafe impl DerefPure for UniqueRc {} + #[unstable(feature = "legacy_receiver_trait", issue = "none")] impl LegacyReceiver for Rc {} @@ -2659,7 +2688,7 @@ impl From<&[T]> for Rc<[T]> { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut [T]> for Rc<[T]> { /// Allocates a reference-counted slice and fills it by cloning `v`'s items. /// @@ -2698,7 +2727,7 @@ impl From<&str> for Rc { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut str> for Rc { /// Allocates a reference-counted string slice and copies `v` into it. /// @@ -2999,12 +3028,7 @@ impl Weak { #[rustc_const_stable(feature = "const_weak_new", since = "1.73.0")] #[must_use] pub const fn new() -> Weak { - Weak { - ptr: unsafe { - NonNull::new_unchecked(ptr::without_provenance_mut::>(usize::MAX)) - }, - alloc: Global, - } + Weak { ptr: NonNull::without_provenance(NonZeroUsize::MAX), alloc: Global } } } @@ -3026,12 +3050,7 @@ impl Weak { #[inline] #[unstable(feature = "allocator_api", issue = "32838")] pub fn new_in(alloc: A) -> Weak { - Weak { - ptr: unsafe { - NonNull::new_unchecked(ptr::without_provenance_mut::>(usize::MAX)) - }, - alloc, - } + Weak { ptr: NonNull::without_provenance(NonZeroUsize::MAX), alloc } } } @@ -3684,22 +3703,266 @@ fn data_offset_align(align: usize) -> usize { /// previous example, `UniqueRc` allows for more flexibility in the construction of cyclic data, /// including fallible or async constructors. #[unstable(feature = "unique_rc_arc", issue = "112566")] -#[derive(Debug)] pub struct UniqueRc< T: ?Sized, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, > { ptr: NonNull>, - phantom: PhantomData>, + // Define the ownership of `RcInner` for drop-check + _marker: PhantomData>, + // Invariance is necessary for soundness: once other `Weak` + // references exist, we already have a form of shared mutability! + _marker2: PhantomData<*mut T>, alloc: A, } +// Not necessary for correctness since `UniqueRc` contains `NonNull`, +// but having an explicit negative impl is nice for documentation purposes +// and results in nicer error messages. +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl !Send for UniqueRc {} + +// Not necessary for correctness since `UniqueRc` contains `NonNull`, +// but having an explicit negative impl is nice for documentation purposes +// and results in nicer error messages. +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl !Sync for UniqueRc {} + #[unstable(feature = "unique_rc_arc", issue = "112566")] impl, U: ?Sized, A: Allocator> CoerceUnsized> for UniqueRc { } +//#[unstable(feature = "unique_rc_arc", issue = "112566")] +#[unstable(feature = "dispatch_from_dyn", issue = "none")] +impl, U: ?Sized> DispatchFromDyn> for UniqueRc {} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl fmt::Display for UniqueRc { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&**self, f) + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl fmt::Debug for UniqueRc { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&**self, f) + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl fmt::Pointer for UniqueRc { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Pointer::fmt(&(&raw const **self), f) + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl borrow::Borrow for UniqueRc { + fn borrow(&self) -> &T { + &**self + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl borrow::BorrowMut for UniqueRc { + fn borrow_mut(&mut self) -> &mut T { + &mut **self + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl AsRef for UniqueRc { + fn as_ref(&self) -> &T { + &**self + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl AsMut for UniqueRc { + fn as_mut(&mut self) -> &mut T { + &mut **self + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl Unpin for UniqueRc {} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl PartialEq for UniqueRc { + /// Equality for two `UniqueRc`s. + /// + /// Two `UniqueRc`s are equal if their inner values are equal. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::rc::UniqueRc; + /// + /// let five = UniqueRc::new(5); + /// + /// assert!(five == UniqueRc::new(5)); + /// ``` + #[inline] + fn eq(&self, other: &Self) -> bool { + PartialEq::eq(&**self, &**other) + } + + /// Inequality for two `UniqueRc`s. + /// + /// Two `UniqueRc`s are not equal if their inner values are not equal. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::rc::UniqueRc; + /// + /// let five = UniqueRc::new(5); + /// + /// assert!(five != UniqueRc::new(6)); + /// ``` + #[inline] + fn ne(&self, other: &Self) -> bool { + PartialEq::ne(&**self, &**other) + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl PartialOrd for UniqueRc { + /// Partial comparison for two `UniqueRc`s. + /// + /// The two are compared by calling `partial_cmp()` on their inner values. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::rc::UniqueRc; + /// use std::cmp::Ordering; + /// + /// let five = UniqueRc::new(5); + /// + /// assert_eq!(Some(Ordering::Less), five.partial_cmp(&UniqueRc::new(6))); + /// ``` + #[inline(always)] + fn partial_cmp(&self, other: &UniqueRc) -> Option { + (**self).partial_cmp(&**other) + } + + /// Less-than comparison for two `UniqueRc`s. + /// + /// The two are compared by calling `<` on their inner values. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::rc::UniqueRc; + /// + /// let five = UniqueRc::new(5); + /// + /// assert!(five < UniqueRc::new(6)); + /// ``` + #[inline(always)] + fn lt(&self, other: &UniqueRc) -> bool { + **self < **other + } + + /// 'Less than or equal to' comparison for two `UniqueRc`s. + /// + /// The two are compared by calling `<=` on their inner values. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::rc::UniqueRc; + /// + /// let five = UniqueRc::new(5); + /// + /// assert!(five <= UniqueRc::new(5)); + /// ``` + #[inline(always)] + fn le(&self, other: &UniqueRc) -> bool { + **self <= **other + } + + /// Greater-than comparison for two `UniqueRc`s. + /// + /// The two are compared by calling `>` on their inner values. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::rc::UniqueRc; + /// + /// let five = UniqueRc::new(5); + /// + /// assert!(five > UniqueRc::new(4)); + /// ``` + #[inline(always)] + fn gt(&self, other: &UniqueRc) -> bool { + **self > **other + } + + /// 'Greater than or equal to' comparison for two `UniqueRc`s. + /// + /// The two are compared by calling `>=` on their inner values. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::rc::UniqueRc; + /// + /// let five = UniqueRc::new(5); + /// + /// assert!(five >= UniqueRc::new(5)); + /// ``` + #[inline(always)] + fn ge(&self, other: &UniqueRc) -> bool { + **self >= **other + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl Ord for UniqueRc { + /// Comparison for two `UniqueRc`s. + /// + /// The two are compared by calling `cmp()` on their inner values. + /// + /// # Examples + /// + /// ``` + /// #![feature(unique_rc_arc)] + /// use std::rc::UniqueRc; + /// use std::cmp::Ordering; + /// + /// let five = UniqueRc::new(5); + /// + /// assert_eq!(Ordering::Less, five.cmp(&UniqueRc::new(6))); + /// ``` + #[inline] + fn cmp(&self, other: &UniqueRc) -> Ordering { + (**self).cmp(&**other) + } +} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl Eq for UniqueRc {} + +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl Hash for UniqueRc { + fn hash(&self, state: &mut H) { + (**self).hash(state); + } +} + // Depends on A = Global impl UniqueRc { /// Creates a new `UniqueRc`. @@ -3735,7 +3998,7 @@ impl UniqueRc { }, alloc, )); - Self { ptr: ptr.into(), phantom: PhantomData, alloc } + Self { ptr: ptr.into(), _marker: PhantomData, _marker2: PhantomData, alloc } } } @@ -3791,9 +4054,6 @@ impl Deref for UniqueRc { } } -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] -unsafe impl PinCoerceUnsized for UniqueRc {} - #[unstable(feature = "unique_rc_arc", issue = "112566")] impl DerefMut for UniqueRc { fn deref_mut(&mut self) -> &mut T { diff --git a/alloc/src/rc/tests.rs b/alloc/src/rc/tests.rs index 333e1bde31c1e..2210a7c24c06a 100644 --- a/alloc/src/rc/tests.rs +++ b/alloc/src/rc/tests.rs @@ -349,9 +349,9 @@ fn test_unsized() { #[test] fn test_maybe_thin_unsized() { // If/when custom thin DSTs exist, this test should be updated to use one - use std::ffi::{CStr, CString}; + use std::ffi::CStr; - let x: Rc = Rc::from(CString::new("swordfish").unwrap().into_boxed_c_str()); + let x: Rc = Rc::from(c"swordfish"); assert_eq!(format!("{x:?}"), "\"swordfish\""); let y: Weak = Rc::downgrade(&x); drop(x); diff --git a/alloc/src/slice.rs b/alloc/src/slice.rs index e3c7835f1d10b..edc8d99f2f990 100644 --- a/alloc/src/slice.rs +++ b/alloc/src/slice.rs @@ -27,6 +27,8 @@ pub use core::slice::ArrayChunksMut; pub use core::slice::ArrayWindows; #[stable(feature = "inherent_ascii_escape", since = "1.60.0")] pub use core::slice::EscapeAscii; +#[unstable(feature = "get_many_mut", issue = "104642")] +pub use core::slice::GetManyMutError; #[stable(feature = "slice_get_slice", since = "1.28.0")] pub use core::slice::SliceIndex; #[cfg(not(no_global_oom_handling))] diff --git a/alloc/src/string.rs b/alloc/src/string.rs index e0576c2551545..0c9535dfaa628 100644 --- a/alloc/src/string.rs +++ b/alloc/src/string.rs @@ -62,10 +62,10 @@ use crate::alloc::Allocator; use crate::borrow::{Cow, ToOwned}; use crate::boxed::Box; use crate::collections::TryReserveError; -use crate::str::{self, Chars, Utf8Error, from_utf8_unchecked_mut}; +use crate::str::{self, CharIndices, Chars, Utf8Error, from_utf8_unchecked_mut}; #[cfg(not(no_global_oom_handling))] use crate::str::{FromStr, from_boxed_utf8_unchecked}; -use crate::vec::Vec; +use crate::vec::{self, Vec}; /// A UTF-8–encoded, growable string. /// @@ -1952,6 +1952,61 @@ impl String { Drain { start, end, iter: chars_iter, string: self_ptr } } + /// Converts a `String` into an iterator over the [`char`]s of the string. + /// + /// As a string consists of valid UTF-8, we can iterate through a string + /// by [`char`]. This method returns such an iterator. + /// + /// It's important to remember that [`char`] represents a Unicode Scalar + /// Value, and might not match your idea of what a 'character' is. Iteration + /// over grapheme clusters may be what you actually want. That functionality + /// is not provided by Rust's standard library, check crates.io instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(string_into_chars)] + /// + /// let word = String::from("goodbye"); + /// + /// let mut chars = word.into_chars(); + /// + /// assert_eq!(Some('g'), chars.next()); + /// assert_eq!(Some('o'), chars.next()); + /// assert_eq!(Some('o'), chars.next()); + /// assert_eq!(Some('d'), chars.next()); + /// assert_eq!(Some('b'), chars.next()); + /// assert_eq!(Some('y'), chars.next()); + /// assert_eq!(Some('e'), chars.next()); + /// + /// assert_eq!(None, chars.next()); + /// ``` + /// + /// Remember, [`char`]s might not match your intuition about characters: + /// + /// ``` + /// #![feature(string_into_chars)] + /// + /// let y = String::from("y̆"); + /// + /// let mut chars = y.into_chars(); + /// + /// assert_eq!(Some('y'), chars.next()); // not 'y̆' + /// assert_eq!(Some('\u{0306}'), chars.next()); + /// + /// assert_eq!(None, chars.next()); + /// ``` + /// + /// [`char`]: prim@char + #[inline] + #[must_use = "`self` will be dropped if the result is not used"] + #[unstable(feature = "string_into_chars", issue = "133125")] + pub fn into_chars(self) -> IntoChars { + IntoChars { bytes: self.into_bytes().into_iter() } + } + /// Removes the specified range in the string, /// and replaces it with the given string. /// The given string doesn't need to be the same length as the range. @@ -2675,14 +2730,28 @@ pub trait ToString { #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] impl ToString for T { + #[inline] + fn to_string(&self) -> String { + ::spec_to_string(self) + } +} + +#[cfg(not(no_global_oom_handling))] +trait SpecToString { + fn spec_to_string(&self) -> String; +} + +#[cfg(not(no_global_oom_handling))] +impl SpecToString for T { // A common guideline is to not inline generic functions. However, // removing `#[inline]` from this method causes non-negligible regressions. // See , the last attempt // to try to remove it. #[inline] - default fn to_string(&self) -> String { + default fn spec_to_string(&self) -> String { let mut buf = String::new(); - let mut formatter = core::fmt::Formatter::new(&mut buf); + let mut formatter = + core::fmt::Formatter::new(&mut buf, core::fmt::FormattingOptions::new()); // Bypass format_args!() to avoid write_str with zero-length strs fmt::Display::fmt(self, &mut formatter) .expect("a Display implementation returned an error unexpectedly"); @@ -2690,42 +2759,34 @@ impl ToString for T { } } -#[doc(hidden)] #[cfg(not(no_global_oom_handling))] -#[unstable(feature = "ascii_char", issue = "110998")] -impl ToString for core::ascii::Char { +impl SpecToString for core::ascii::Char { #[inline] - fn to_string(&self) -> String { + fn spec_to_string(&self) -> String { self.as_str().to_owned() } } -#[doc(hidden)] #[cfg(not(no_global_oom_handling))] -#[stable(feature = "char_to_string_specialization", since = "1.46.0")] -impl ToString for char { +impl SpecToString for char { #[inline] - fn to_string(&self) -> String { + fn spec_to_string(&self) -> String { String::from(self.encode_utf8(&mut [0; 4])) } } -#[doc(hidden)] #[cfg(not(no_global_oom_handling))] -#[stable(feature = "bool_to_string_specialization", since = "1.68.0")] -impl ToString for bool { +impl SpecToString for bool { #[inline] - fn to_string(&self) -> String { + fn spec_to_string(&self) -> String { String::from(if *self { "true" } else { "false" }) } } -#[doc(hidden)] #[cfg(not(no_global_oom_handling))] -#[stable(feature = "u8_to_string_specialization", since = "1.54.0")] -impl ToString for u8 { +impl SpecToString for u8 { #[inline] - fn to_string(&self) -> String { + fn spec_to_string(&self) -> String { let mut buf = String::with_capacity(3); let mut n = *self; if n >= 10 { @@ -2741,12 +2802,10 @@ impl ToString for u8 { } } -#[doc(hidden)] #[cfg(not(no_global_oom_handling))] -#[stable(feature = "i8_to_string_specialization", since = "1.54.0")] -impl ToString for i8 { +impl SpecToString for i8 { #[inline] - fn to_string(&self) -> String { + fn spec_to_string(&self) -> String { let mut buf = String::with_capacity(4); if self.is_negative() { buf.push('-'); @@ -2787,11 +2846,9 @@ macro_rules! to_string_expr_wrap_in_deref { macro_rules! to_string_str { {$($($x:ident)*),+} => { $( - #[doc(hidden)] - #[stable(feature = "str_to_string_specialization", since = "1.9.0")] - impl ToString for to_string_str_wrap_in_ref!($($x)*) { + impl SpecToString for to_string_str_wrap_in_ref!($($x)*) { #[inline] - fn to_string(&self) -> String { + fn spec_to_string(&self) -> String { String::from(to_string_expr_wrap_in_deref!(self ; $($x)*)) } } @@ -2815,32 +2872,26 @@ to_string_str! { x, } -#[doc(hidden)] #[cfg(not(no_global_oom_handling))] -#[stable(feature = "cow_str_to_string_specialization", since = "1.17.0")] -impl ToString for Cow<'_, str> { +impl SpecToString for Cow<'_, str> { #[inline] - fn to_string(&self) -> String { + fn spec_to_string(&self) -> String { self[..].to_owned() } } -#[doc(hidden)] #[cfg(not(no_global_oom_handling))] -#[stable(feature = "string_to_string_specialization", since = "1.17.0")] -impl ToString for String { +impl SpecToString for String { #[inline] - fn to_string(&self) -> String { + fn spec_to_string(&self) -> String { self.to_owned() } } -#[doc(hidden)] #[cfg(not(no_global_oom_handling))] -#[stable(feature = "fmt_arguments_to_string_specialization", since = "1.71.0")] -impl ToString for fmt::Arguments<'_> { +impl SpecToString for fmt::Arguments<'_> { #[inline] - fn to_string(&self) -> String { + fn spec_to_string(&self) -> String { crate::fmt::format(*self) } } @@ -3094,6 +3145,134 @@ impl fmt::Write for String { } } +/// An iterator over the [`char`]s of a string. +/// +/// This struct is created by the [`into_chars`] method on [`String`]. +/// See its documentation for more. +/// +/// [`char`]: prim@char +/// [`into_chars`]: String::into_chars +#[cfg_attr(not(no_global_oom_handling), derive(Clone))] +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[unstable(feature = "string_into_chars", issue = "133125")] +pub struct IntoChars { + bytes: vec::IntoIter, +} + +#[unstable(feature = "string_into_chars", issue = "133125")] +impl fmt::Debug for IntoChars { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("IntoChars").field(&self.as_str()).finish() + } +} + +impl IntoChars { + /// Views the underlying data as a subslice of the original data. + /// + /// # Examples + /// + /// ``` + /// #![feature(string_into_chars)] + /// + /// let mut chars = String::from("abc").into_chars(); + /// + /// assert_eq!(chars.as_str(), "abc"); + /// chars.next(); + /// assert_eq!(chars.as_str(), "bc"); + /// chars.next(); + /// chars.next(); + /// assert_eq!(chars.as_str(), ""); + /// ``` + #[unstable(feature = "string_into_chars", issue = "133125")] + #[must_use] + #[inline] + pub fn as_str(&self) -> &str { + // SAFETY: `bytes` is a valid UTF-8 string. + unsafe { str::from_utf8_unchecked(self.bytes.as_slice()) } + } + + /// Consumes the `IntoChars`, returning the remaining string. + /// + /// # Examples + /// + /// ``` + /// #![feature(string_into_chars)] + /// + /// let chars = String::from("abc").into_chars(); + /// assert_eq!(chars.into_string(), "abc"); + /// + /// let mut chars = String::from("def").into_chars(); + /// chars.next(); + /// assert_eq!(chars.into_string(), "ef"); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "string_into_chars", issue = "133125")] + #[inline] + pub fn into_string(self) -> String { + // Safety: `bytes` are kept in UTF-8 form, only removing whole `char`s at a time. + unsafe { String::from_utf8_unchecked(self.bytes.collect()) } + } + + #[inline] + fn iter(&self) -> CharIndices<'_> { + self.as_str().char_indices() + } +} + +#[unstable(feature = "string_into_chars", issue = "133125")] +impl Iterator for IntoChars { + type Item = char; + + #[inline] + fn next(&mut self) -> Option { + let mut iter = self.iter(); + match iter.next() { + None => None, + Some((_, ch)) => { + let offset = iter.offset(); + // `offset` is a valid index. + let _ = self.bytes.advance_by(offset); + Some(ch) + } + } + } + + #[inline] + fn count(self) -> usize { + self.iter().count() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter().size_hint() + } + + #[inline] + fn last(mut self) -> Option { + self.next_back() + } +} + +#[unstable(feature = "string_into_chars", issue = "133125")] +impl DoubleEndedIterator for IntoChars { + #[inline] + fn next_back(&mut self) -> Option { + let len = self.as_str().len(); + let mut iter = self.iter(); + match iter.next_back() { + None => None, + Some((idx, ch)) => { + // `idx` is a valid index. + let _ = self.bytes.advance_back_by(len - idx); + Some(ch) + } + } + } +} + +#[unstable(feature = "string_into_chars", issue = "133125")] +impl FusedIterator for IntoChars {} + /// A draining iterator for `String`. /// /// This struct is created by the [`drain`] method on [`String`]. See its diff --git a/alloc/src/sync.rs b/alloc/src/sync.rs index da2d6bb3bce24..11e7128e67771 100644 --- a/alloc/src/sync.rs +++ b/alloc/src/sync.rs @@ -18,6 +18,7 @@ use core::intrinsics::abort; use core::iter; use core::marker::{PhantomData, Unsize}; use core::mem::{self, ManuallyDrop, align_of_val_raw}; +use core::num::NonZeroUsize; use core::ops::{CoerceUnsized, Deref, DerefPure, DispatchFromDyn, LegacyReceiver}; use core::panic::{RefUnwindSafe, UnwindSafe}; use core::pin::{Pin, PinCoerceUnsized}; @@ -39,9 +40,6 @@ use crate::string::String; #[cfg(not(no_global_oom_handling))] use crate::vec::Vec; -#[cfg(test)] -mod tests; - /// A soft limit on the amount of references that may be made to an `Arc`. /// /// Going above this limit will abort your program (although not @@ -235,7 +233,7 @@ macro_rules! acquire { /// counting in general. /// /// [rc_examples]: crate::rc#examples -#[cfg_attr(not(bootstrap), doc(search_unbox))] +#[doc(search_unbox)] #[cfg_attr(not(test), rustc_diagnostic_item = "Arc")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_insignificant_dtor] @@ -787,7 +785,7 @@ impl Arc { let uninit_ptr: NonNull<_> = (unsafe { &mut *uninit_raw_ptr }).into(); let init_ptr: NonNull> = uninit_ptr.cast(); - let weak = Weak { ptr: init_ptr, alloc: alloc }; + let weak = Weak { ptr: init_ptr, alloc }; // It's important we don't give up ownership of the weak pointer, or // else the memory might be freed by the time `data_fn` returns. If @@ -1206,6 +1204,26 @@ impl Arc<[T]> { )) } } + + /// Converts the reference-counted slice into a reference-counted array. + /// + /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub fn into_array(self) -> Option> { + if self.len() == N { + let ptr = Self::into_raw(self) as *const [T; N]; + + // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. + let me = unsafe { Arc::from_raw(ptr) }; + Some(me) + } else { + None + } + } } impl Arc<[T], A> { @@ -2451,7 +2469,7 @@ impl Arc { /// let x: Arc<&str> = Arc::new("Hello, world!"); /// { /// let s = String::from("Oh, no!"); - /// let mut y: Arc<&str> = x.clone().into(); + /// let mut y: Arc<&str> = x.clone(); /// unsafe { /// // this is Undefined Behavior, because x's inner type /// // is &'long str, not &'short str @@ -2670,12 +2688,7 @@ impl Weak { #[rustc_const_stable(feature = "const_weak_new", since = "1.73.0")] #[must_use] pub const fn new() -> Weak { - Weak { - ptr: unsafe { - NonNull::new_unchecked(ptr::without_provenance_mut::>(usize::MAX)) - }, - alloc: Global, - } + Weak { ptr: NonNull::without_provenance(NonZeroUsize::MAX), alloc: Global } } } @@ -2700,12 +2713,7 @@ impl Weak { #[inline] #[unstable(feature = "allocator_api", issue = "32838")] pub fn new_in(alloc: A) -> Weak { - Weak { - ptr: unsafe { - NonNull::new_unchecked(ptr::without_provenance_mut::>(usize::MAX)) - }, - alloc, - } + Weak { ptr: NonNull::without_provenance(NonZeroUsize::MAX), alloc } } } @@ -3618,7 +3626,7 @@ impl From<&[T]> for Arc<[T]> { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut [T]> for Arc<[T]> { /// Allocates a reference-counted slice and fills it by cloning `v`'s items. /// @@ -3657,7 +3665,7 @@ impl From<&str> for Arc { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut str> for Arc { /// Allocates a reference-counted `str` and copies `v` into it. /// diff --git a/alloc/src/task.rs b/alloc/src/task.rs index 0f8e74300a491..b4116f4988b64 100644 --- a/alloc/src/task.rs +++ b/alloc/src/task.rs @@ -199,7 +199,6 @@ fn raw_waker(waker: Arc) -> RawWaker { /// /// ```rust /// #![feature(local_waker)] -/// #![feature(noop_waker)] /// use std::task::{LocalWake, ContextBuilder, LocalWaker, Waker}; /// use std::future::Future; /// use std::pin::Pin; diff --git a/alloc/src/vec/extract_if.rs b/alloc/src/vec/extract_if.rs index 72d51e8904488..4db13981596bc 100644 --- a/alloc/src/vec/extract_if.rs +++ b/alloc/src/vec/extract_if.rs @@ -1,3 +1,4 @@ +use core::ops::{Range, RangeBounds}; use core::{ptr, slice}; use super::Vec; @@ -14,7 +15,7 @@ use crate::alloc::{Allocator, Global}; /// #![feature(extract_if)] /// /// let mut v = vec![0, 1, 2]; -/// let iter: std::vec::ExtractIf<'_, _, _> = v.extract_if(|x| *x % 2 == 0); +/// let iter: std::vec::ExtractIf<'_, _, _> = v.extract_if(.., |x| *x % 2 == 0); /// ``` #[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] #[derive(Debug)] @@ -24,24 +25,32 @@ pub struct ExtractIf< T, F, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, -> where - F: FnMut(&mut T) -> bool, -{ - pub(super) vec: &'a mut Vec, +> { + vec: &'a mut Vec, /// The index of the item that will be inspected by the next call to `next`. - pub(super) idx: usize, + idx: usize, + /// Elements at and beyond this point will be retained. Must be equal or smaller than `old_len`. + end: usize, /// The number of items that have been drained (removed) thus far. - pub(super) del: usize, + del: usize, /// The original length of `vec` prior to draining. - pub(super) old_len: usize, + old_len: usize, /// The filter test predicate. - pub(super) pred: F, + pred: F, } -impl ExtractIf<'_, T, F, A> -where - F: FnMut(&mut T) -> bool, -{ +impl<'a, T, F, A: Allocator> ExtractIf<'a, T, F, A> { + pub(super) fn new>(vec: &'a mut Vec, pred: F, range: R) -> Self { + let old_len = vec.len(); + let Range { start, end } = slice::range(range, ..old_len); + + // Guard against the vec getting leaked (leak amplification) + unsafe { + vec.set_len(0); + } + ExtractIf { vec, idx: start, del: 0, end, old_len, pred } + } + /// Returns a reference to the underlying allocator. #[unstable(feature = "allocator_api", issue = "32838")] #[inline] @@ -59,7 +68,7 @@ where fn next(&mut self) -> Option { unsafe { - while self.idx < self.old_len { + while self.idx < self.end { let i = self.idx; let v = slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len); let drained = (self.pred)(&mut v[i]); @@ -82,24 +91,15 @@ where } fn size_hint(&self) -> (usize, Option) { - (0, Some(self.old_len - self.idx)) + (0, Some(self.end - self.idx)) } } #[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] -impl Drop for ExtractIf<'_, T, F, A> -where - F: FnMut(&mut T) -> bool, -{ +impl Drop for ExtractIf<'_, T, F, A> { fn drop(&mut self) { unsafe { if self.idx < self.old_len && self.del > 0 { - // This is a pretty messed up state, and there isn't really an - // obviously right thing to do. We don't want to keep trying - // to execute `pred`, so we just backshift all the unprocessed - // elements and tell the vec that they still exist. The backshift - // is required to prevent a double-drop of the last successfully - // drained item prior to a panic in the predicate. let ptr = self.vec.as_mut_ptr(); let src = ptr.add(self.idx); let dst = src.sub(self.del); diff --git a/alloc/src/vec/is_zero.rs b/alloc/src/vec/is_zero.rs index ba57d940d8c99..a3ddd6f6e230e 100644 --- a/alloc/src/vec/is_zero.rs +++ b/alloc/src/vec/is_zero.rs @@ -40,19 +40,8 @@ impl_is_zero!(char, |x| x == '\0'); impl_is_zero!(f32, |x: f32| x.to_bits() == 0); impl_is_zero!(f64, |x: f64| x.to_bits() == 0); -unsafe impl IsZero for *const T { - #[inline] - fn is_zero(&self) -> bool { - (*self).is_null() - } -} - -unsafe impl IsZero for *mut T { - #[inline] - fn is_zero(&self) -> bool { - (*self).is_null() - } -} +// `IsZero` cannot be soundly implemented for pointers because of provenance +// (see #135338). unsafe impl IsZero for [T; N] { #[inline] diff --git a/alloc/src/vec/mod.rs b/alloc/src/vec/mod.rs index 990b7e8f76127..cd2afd7a47319 100644 --- a/alloc/src/vec/mod.rs +++ b/alloc/src/vec/mod.rs @@ -56,7 +56,6 @@ #[cfg(not(no_global_oom_handling))] use core::cmp; use core::cmp::Ordering; -use core::fmt; use core::hash::{Hash, Hasher}; #[cfg(not(no_global_oom_handling))] use core::iter; @@ -65,6 +64,7 @@ use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties}; use core::ops::{self, Index, IndexMut, Range, RangeBounds}; use core::ptr::{self, NonNull}; use core::slice::{self, SliceIndex}; +use core::{fmt, intrinsics}; #[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] pub use self::extract_if::ExtractIf; @@ -427,7 +427,7 @@ impl Vec { /// /// The vector will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the vector will not allocate. + /// `capacity`. If `capacity` is zero, the vector will not allocate. /// /// It is important to note that although the returned vector has the /// minimum *capacity* specified, the vector will have a zero *length*. For @@ -487,7 +487,7 @@ impl Vec { /// /// The vector will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the vector will not allocate. + /// `capacity`. If `capacity` is zero, the vector will not allocate. /// /// # Errors /// @@ -745,7 +745,7 @@ impl Vec { /// /// The vector will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the vector will not allocate. + /// `capacity`. If `capacity` is zero, the vector will not allocate. /// /// It is important to note that although the returned vector has the /// minimum *capacity* specified, the vector will have a zero *length*. For @@ -808,7 +808,7 @@ impl Vec { /// /// The vector will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the vector will not allocate. + /// `capacity`. If `capacity` is zero, the vector will not allocate. /// /// # Errors /// @@ -1662,7 +1662,7 @@ impl Vec { #[stable(feature = "vec_as_ptr", since = "1.37.0")] #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] #[rustc_never_returns_null_ptr] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[inline] pub const fn as_ptr(&self) -> *const T { // We shadow the slice method of the same name to avoid going through @@ -1725,7 +1725,7 @@ impl Vec { #[stable(feature = "vec_as_ptr", since = "1.37.0")] #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] #[rustc_never_returns_null_ptr] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[inline] pub const fn as_mut_ptr(&mut self) -> *mut T { // We shadow the slice method of the same name to avoid going through @@ -1824,7 +1824,10 @@ impl Vec { /// /// # Examples /// - /// This method can be useful for situations in which the vector + /// See [`spare_capacity_mut()`] for an example with safe + /// initialization of capacity elements and use of this method. + /// + /// `set_len()` can be useful for situations in which the vector /// is serving as a buffer for other code, particularly over FFI: /// /// ```no_run @@ -1884,6 +1887,8 @@ impl Vec { /// /// Normally, here, one would use [`clear`] instead to correctly drop /// the contents and thus not leak memory. + /// + /// [`spare_capacity_mut()`]: Vec::spare_capacity_mut #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn set_len(&mut self, new_len: usize) { @@ -1953,11 +1958,11 @@ impl Vec { /// # Examples /// /// ``` - /// let mut vec = vec![1, 2, 3]; - /// vec.insert(1, 4); - /// assert_eq!(vec, [1, 4, 2, 3]); - /// vec.insert(4, 5); - /// assert_eq!(vec, [1, 4, 2, 3, 5]); + /// let mut vec = vec!['a', 'b', 'c']; + /// vec.insert(1, 'd'); + /// assert_eq!(vec, ['a', 'd', 'b', 'c']); + /// vec.insert(4, 'e'); + /// assert_eq!(vec, ['a', 'd', 'b', 'c', 'e']); /// ``` /// /// # Time complexity @@ -2024,9 +2029,9 @@ impl Vec { /// # Examples /// /// ``` - /// let mut v = vec![1, 2, 3]; - /// assert_eq!(v.remove(1), 2); - /// assert_eq!(v, [1, 3]); + /// let mut v = vec!['a', 'b', 'c']; + /// assert_eq!(v.remove(1), 'b'); + /// assert_eq!(v, ['a', 'c']); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[track_caller] @@ -2675,7 +2680,14 @@ impl Vec { #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] #[rustc_confusables("length", "size")] pub const fn len(&self) -> usize { - self.len + let len = self.len; + + // SAFETY: The maximum capacity of `Vec` is `isize::MAX` bytes, so the maximum value can + // be returned is `usize::checked_div(mem::size_of::()).unwrap_or(usize::MAX)`, which + // matches the definition of `T::MAX_SLICE_LEN`. + unsafe { intrinsics::assume(len <= T::MAX_SLICE_LEN) }; + + len } /// Returns `true` if the vector contains no elements. @@ -2715,10 +2727,10 @@ impl Vec { /// # Examples /// /// ``` - /// let mut vec = vec![1, 2, 3]; + /// let mut vec = vec!['a', 'b', 'c']; /// let vec2 = vec.split_off(1); - /// assert_eq!(vec, [1]); - /// assert_eq!(vec2, [2, 3]); + /// assert_eq!(vec, ['a']); + /// assert_eq!(vec2, ['b', 'c']); /// ``` #[cfg(not(no_global_oom_handling))] #[inline] @@ -2982,9 +2994,9 @@ impl Vec { /// vec.resize(3, "world"); /// assert_eq!(vec, ["hello", "world", "world"]); /// - /// let mut vec = vec![1, 2, 3, 4]; - /// vec.resize(2, 0); - /// assert_eq!(vec, [1, 2]); + /// let mut vec = vec!['a', 'b', 'c', 'd']; + /// vec.resize(2, '_'); + /// assert_eq!(vec, ['a', 'b']); /// ``` #[cfg(not(no_global_oom_handling))] #[stable(feature = "vec_resize", since = "1.5.0")] @@ -3025,26 +3037,29 @@ impl Vec { self.spec_extend(other.iter()) } - /// Copies elements from `src` range to the end of the vector. + /// Given a range `src`, clones a slice of elements in that range and appends it to the end. + /// + /// `src` must be a range that can form a valid subslice of the `Vec`. /// /// # Panics /// - /// Panics if the starting point is greater than the end point or if - /// the end point is greater than the length of the vector. + /// Panics if starting index is greater than the end index + /// or if the index is greater than the length of the vector. /// /// # Examples /// /// ``` - /// let mut vec = vec![0, 1, 2, 3, 4]; + /// let mut characters = vec!['a', 'b', 'c', 'd', 'e']; + /// characters.extend_from_within(2..); + /// assert_eq!(characters, ['a', 'b', 'c', 'd', 'e', 'c', 'd', 'e']); /// - /// vec.extend_from_within(2..); - /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]); + /// let mut numbers = vec![0, 1, 2, 3, 4]; + /// numbers.extend_from_within(..2); + /// assert_eq!(numbers, [0, 1, 2, 3, 4, 0, 1]); /// - /// vec.extend_from_within(..2); - /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]); - /// - /// vec.extend_from_within(4..8); - /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]); + /// let mut strings = vec![String::from("hello"), String::from("world"), String::from("!")]; + /// strings.extend_from_within(1..=2); + /// assert_eq!(strings, ["hello", "world", "!", "world", "!"]); /// ``` #[cfg(not(no_global_oom_handling))] #[stable(feature = "vec_extend_from_within", since = "1.53.0")] @@ -3572,7 +3587,7 @@ impl Vec { /// with the given `replace_with` iterator and yields the removed items. /// `replace_with` does not need to be the same length as `range`. /// - /// `range` is removed even if the iterator is not consumed until the end. + /// `range` is removed even if the `Splice` iterator is not consumed before it is dropped. /// /// It is unspecified how many elements are removed from the vector /// if the `Splice` value is leaked. @@ -3598,8 +3613,18 @@ impl Vec { /// let mut v = vec![1, 2, 3, 4]; /// let new = [7, 8, 9]; /// let u: Vec<_> = v.splice(1..3, new).collect(); - /// assert_eq!(v, &[1, 7, 8, 9, 4]); - /// assert_eq!(u, &[2, 3]); + /// assert_eq!(v, [1, 7, 8, 9, 4]); + /// assert_eq!(u, [2, 3]); + /// ``` + /// + /// Using `splice` to insert new items into a vector efficiently at a specific position + /// indicated by an empty range: + /// + /// ``` + /// let mut v = vec![1, 5]; + /// let new = [2, 3, 4]; + /// v.splice(1..1, new); + /// assert_eq!(v, [1, 2, 3, 4, 5]); /// ``` #[cfg(not(no_global_oom_handling))] #[inline] @@ -3612,12 +3637,15 @@ impl Vec { Splice { drain: self.drain(range), replace_with: replace_with.into_iter() } } - /// Creates an iterator which uses a closure to determine if an element should be removed. + /// Creates an iterator which uses a closure to determine if element in the range should be removed. /// /// If the closure returns true, then the element is removed and yielded. /// If the closure returns false, the element will remain in the vector and will not be yielded /// by the iterator. /// + /// Only elements that fall in the provided range are considered for extraction, but any elements + /// after the range will still have to be moved if any element has been extracted. + /// /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating /// or the iteration short-circuits, then the remaining elements will be retained. /// Use [`retain`] with a negated predicate if you do not need the returned iterator. @@ -3627,10 +3655,12 @@ impl Vec { /// Using this method is equivalent to the following code: /// /// ``` + /// # use std::cmp::min; /// # let some_predicate = |x: &mut i32| { *x == 2 || *x == 3 || *x == 6 }; /// # let mut vec = vec![1, 2, 3, 4, 5, 6]; - /// let mut i = 0; - /// while i < vec.len() { + /// # let range = 1..4; + /// let mut i = range.start; + /// while i < min(vec.len(), range.end) { /// if some_predicate(&mut vec[i]) { /// let val = vec.remove(i); /// // your code here @@ -3645,8 +3675,12 @@ impl Vec { /// But `extract_if` is easier to use. `extract_if` is also more efficient, /// because it can backshift the elements of the array in bulk. /// - /// Note that `extract_if` also lets you mutate every element in the filter closure, - /// regardless of whether you choose to keep or remove it. + /// Note that `extract_if` also lets you mutate the elements passed to the filter closure, + /// regardless of whether you choose to keep or remove them. + /// + /// # Panics + /// + /// If `range` is out of bounds. /// /// # Examples /// @@ -3656,25 +3690,29 @@ impl Vec { /// #![feature(extract_if)] /// let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15]; /// - /// let evens = numbers.extract_if(|x| *x % 2 == 0).collect::>(); + /// let evens = numbers.extract_if(.., |x| *x % 2 == 0).collect::>(); /// let odds = numbers; /// /// assert_eq!(evens, vec![2, 4, 6, 8, 14]); /// assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]); /// ``` + /// + /// Using the range argument to only process a part of the vector: + /// + /// ``` + /// #![feature(extract_if)] + /// let mut items = vec![0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 1, 2]; + /// let ones = items.extract_if(7.., |x| *x == 1).collect::>(); + /// assert_eq!(items, vec![0, 0, 0, 0, 0, 0, 0, 2, 2, 2]); + /// assert_eq!(ones.len(), 3); + /// ``` #[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] - pub fn extract_if(&mut self, filter: F) -> ExtractIf<'_, T, F, A> + pub fn extract_if(&mut self, range: R, filter: F) -> ExtractIf<'_, T, F, A> where F: FnMut(&mut T) -> bool, + R: RangeBounds, { - let old_len = self.len(); - - // Guard against us getting leaked (leak amplification) - unsafe { - self.set_len(0); - } - - ExtractIf { vec: self, idx: 0, del: 0, old_len, pred: filter } + ExtractIf::new(self, filter, range) } } diff --git a/alloc/src/alloc/tests.rs b/alloc/tests/alloc.rs similarity index 93% rename from alloc/src/alloc/tests.rs rename to alloc/tests/alloc.rs index 5d6077f057a2c..1e722d667955c 100644 --- a/alloc/src/alloc/tests.rs +++ b/alloc/tests/alloc.rs @@ -1,10 +1,9 @@ -use super::*; +use alloc::alloc::*; +use alloc::boxed::Box; extern crate test; use test::Bencher; -use crate::boxed::Box; - #[test] fn allocate_zeroed() { unsafe { diff --git a/alloc/tests/boxed.rs b/alloc/tests/boxed.rs index 6a8ba5c92fb30..94389cf2de933 100644 --- a/alloc/tests/boxed.rs +++ b/alloc/tests/boxed.rs @@ -4,7 +4,7 @@ use core::mem::MaybeUninit; use core::ptr::NonNull; #[test] -#[cfg_attr(not(bootstrap), expect(dangling_pointers_from_temporaries))] +#[expect(dangling_pointers_from_temporaries)] fn uninitialized_zero_size_box() { assert_eq!( &*Box::<()>::new_uninit() as *const _, diff --git a/alloc/src/ffi/c_str/tests.rs b/alloc/tests/c_str2.rs similarity index 97% rename from alloc/src/ffi/c_str/tests.rs rename to alloc/tests/c_str2.rs index 8b7172b3f20a9..0f4c27fa12322 100644 --- a/alloc/src/ffi/c_str/tests.rs +++ b/alloc/tests/c_str2.rs @@ -1,11 +1,12 @@ +use alloc::ffi::CString; +use alloc::rc::Rc; +use alloc::sync::Arc; use core::assert_matches::assert_matches; -use core::ffi::FromBytesUntilNulError; +use core::ffi::{CStr, FromBytesUntilNulError, c_char}; #[allow(deprecated)] use core::hash::SipHasher13 as DefaultHasher; use core::hash::{Hash, Hasher}; -use super::*; - #[test] fn c_to_rust() { let data = b"123\0"; @@ -159,7 +160,7 @@ fn boxed_default() { #[test] fn test_c_str_clone_into() { - let mut c_string = CString::new("lorem").unwrap(); + let mut c_string = c"lorem".to_owned(); let c_ptr = c_string.as_ptr(); let c_str = CStr::from_bytes_with_nul(b"ipsum\0").unwrap(); c_str.clone_into(&mut c_string); diff --git a/alloc/src/collections/binary_heap/tests.rs b/alloc/tests/collections/binary_heap.rs similarity index 99% rename from alloc/src/collections/binary_heap/tests.rs rename to alloc/tests/collections/binary_heap.rs index ad0a020a1a961..55405ffe8c4f6 100644 --- a/alloc/src/collections/binary_heap/tests.rs +++ b/alloc/tests/collections/binary_heap.rs @@ -1,7 +1,9 @@ +use alloc::boxed::Box; +use alloc::collections::binary_heap::*; +use std::iter::TrustedLen; +use std::mem; use std::panic::{AssertUnwindSafe, catch_unwind}; -use super::*; -use crate::boxed::Box; use crate::testing::crash_test::{CrashTestDummy, Panic}; #[test] @@ -531,7 +533,7 @@ fn panic_safe() { self.0.partial_cmp(&other.0) } } - let mut rng = crate::test_helpers::test_rng(); + let mut rng = crate::test_rng(); const DATASZ: usize = 32; // Miri is too slow let ntest = if cfg!(miri) { 1 } else { 10 }; diff --git a/alloc/tests/collections/mod.rs b/alloc/tests/collections/mod.rs new file mode 100644 index 0000000000000..e73f3aaef8c83 --- /dev/null +++ b/alloc/tests/collections/mod.rs @@ -0,0 +1 @@ +mod binary_heap; diff --git a/alloc/tests/lib.rs b/alloc/tests/lib.rs index 699a8e6776e6d..393bdfe48b741 100644 --- a/alloc/tests/lib.rs +++ b/alloc/tests/lib.rs @@ -4,11 +4,11 @@ #![feature(assert_matches)] #![feature(btree_extract_if)] #![feature(cow_is_borrowed)] -#![feature(const_heap)] -#![feature(const_try)] #![feature(core_intrinsics)] +#![feature(downcast_unchecked)] #![feature(extract_if)] #![feature(exact_size_is_empty)] +#![feature(hashmap_internals)] #![feature(linked_list_cursors)] #![feature(map_try_insert)] #![feature(pattern)] @@ -31,11 +31,12 @@ #![feature(const_str_from_utf8)] #![feature(panic_update_hook)] #![feature(pointer_is_aligned_to)] +#![feature(test)] #![feature(thin_box)] -#![cfg_attr(bootstrap, feature(strict_provenance))] -#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))] #![feature(drain_keep_rest)] #![feature(local_waker)] +#![feature(str_as_str)] +#![feature(strict_provenance_lints)] #![feature(vec_pop_if)] #![feature(unique_rc_arc)] #![feature(macro_metavar_expr_concat)] @@ -43,25 +44,33 @@ #![deny(fuzzy_provenance_casts)] #![deny(unsafe_op_in_unsafe_fn)] +extern crate test; + use std::hash::{DefaultHasher, Hash, Hasher}; +mod alloc; mod arc; mod autotraits; mod borrow; mod boxed; mod btree_set_hash; mod c_str; +mod c_str2; +mod collections; mod const_fns; mod cow_str; mod fmt; mod heap; mod linked_list; +mod misc_tests; mod rc; mod slice; mod sort; mod str; mod string; +mod sync; mod task; +mod testing; mod thin_box; mod vec; mod vec_deque; @@ -72,6 +81,18 @@ fn hash(t: &T) -> u64 { s.finish() } +/// Copied from `std::test_helpers::test_rng`, since these tests rely on the +/// seed not being the same for every RNG invocation too. +fn test_rng() -> rand_xorshift::XorShiftRng { + use std::hash::{BuildHasher, Hash, Hasher}; + let mut hasher = std::hash::RandomState::new().build_hasher(); + std::panic::Location::caller().hash(&mut hasher); + let hc64 = hasher.finish(); + let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::>(); + let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap(); + rand::SeedableRng::from_seed(seed) +} + // FIXME: Instantiated functions with i128 in the signature is not supported in Emscripten. // See https://github.com/kripken/emscripten-fastcomp/issues/169 #[cfg(not(target_os = "emscripten"))] diff --git a/alloc/src/tests.rs b/alloc/tests/misc_tests.rs similarity index 100% rename from alloc/src/tests.rs rename to alloc/tests/misc_tests.rs diff --git a/alloc/tests/sort/tests.rs b/alloc/tests/sort/tests.rs index 14e6013f965d8..4cc79010e8fed 100644 --- a/alloc/tests/sort/tests.rs +++ b/alloc/tests/sort/tests.rs @@ -33,7 +33,7 @@ fn check_is_sorted(v: &mut [T]) { known_good_stable_sort::sort(known_good_sorted_vec.as_mut_slice()); if is_small_test { - eprintln!("Orginal: {:?}", v_orig); + eprintln!("Original: {:?}", v_orig); eprintln!("Expected: {:?}", known_good_sorted_vec); eprintln!("Got: {:?}", v); } else { diff --git a/alloc/src/sync/tests.rs b/alloc/tests/sync.rs similarity index 98% rename from alloc/src/sync/tests.rs rename to alloc/tests/sync.rs index 3f66c88992344..7a9a4abfdc672 100644 --- a/alloc/src/sync/tests.rs +++ b/alloc/tests/sync.rs @@ -1,14 +1,16 @@ +use alloc::sync::*; +use std::alloc::{AllocError, Allocator, Layout}; +use std::any::Any; use std::clone::Clone; use std::mem::MaybeUninit; use std::option::Option::None; +use std::ptr::NonNull; use std::sync::Mutex; -use std::sync::atomic::AtomicUsize; -use std::sync::atomic::Ordering::SeqCst; +use std::sync::atomic::Ordering::*; +use std::sync::atomic::{self, AtomicUsize}; use std::sync::mpsc::channel; use std::thread; -use super::*; - struct Canary(*mut AtomicUsize); impl Drop for Canary { @@ -412,9 +414,9 @@ fn test_unsized() { #[test] fn test_maybe_thin_unsized() { // If/when custom thin DSTs exist, this test should be updated to use one - use std::ffi::{CStr, CString}; + use std::ffi::CStr; - let x: Arc = Arc::from(CString::new("swordfish").unwrap().into_boxed_c_str()); + let x: Arc = Arc::from(c"swordfish"); assert_eq!(format!("{x:?}"), "\"swordfish\""); let y: Weak = Arc::downgrade(&x); drop(x); diff --git a/alloc/tests/testing/crash_test.rs b/alloc/tests/testing/crash_test.rs new file mode 100644 index 0000000000000..502fe6c10c6fd --- /dev/null +++ b/alloc/tests/testing/crash_test.rs @@ -0,0 +1,80 @@ +use std::cmp::Ordering; +use std::fmt::Debug; +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering::SeqCst; + +/// A blueprint for crash test dummy instances that monitor drops. +/// Some instances may be configured to panic at some point. +/// +/// Crash test dummies are identified and ordered by an id, so they can be used +/// as keys in a BTreeMap. +#[derive(Debug)] +pub struct CrashTestDummy { + pub id: usize, + dropped: AtomicUsize, +} + +impl CrashTestDummy { + /// Creates a crash test dummy design. The `id` determines order and equality of instances. + pub fn new(id: usize) -> CrashTestDummy { + CrashTestDummy { id, dropped: AtomicUsize::new(0) } + } + + /// Creates an instance of a crash test dummy that records what events it experiences + /// and optionally panics. + pub fn spawn(&self, panic: Panic) -> Instance<'_> { + Instance { origin: self, panic } + } + + /// Returns how many times instances of the dummy have been dropped. + pub fn dropped(&self) -> usize { + self.dropped.load(SeqCst) + } +} + +#[derive(Debug)] +pub struct Instance<'a> { + origin: &'a CrashTestDummy, + panic: Panic, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum Panic { + Never, + InDrop, +} + +impl Instance<'_> { + pub fn id(&self) -> usize { + self.origin.id + } +} + +impl Drop for Instance<'_> { + fn drop(&mut self) { + self.origin.dropped.fetch_add(1, SeqCst); + if self.panic == Panic::InDrop { + panic!("panic in `drop`"); + } + } +} + +impl PartialOrd for Instance<'_> { + fn partial_cmp(&self, other: &Self) -> Option { + self.id().partial_cmp(&other.id()) + } +} + +impl Ord for Instance<'_> { + fn cmp(&self, other: &Self) -> Ordering { + self.id().cmp(&other.id()) + } +} + +impl PartialEq for Instance<'_> { + fn eq(&self, other: &Self) -> bool { + self.id().eq(&other.id()) + } +} + +impl Eq for Instance<'_> {} diff --git a/alloc/tests/testing/mod.rs b/alloc/tests/testing/mod.rs new file mode 100644 index 0000000000000..0a3dd191dc891 --- /dev/null +++ b/alloc/tests/testing/mod.rs @@ -0,0 +1 @@ +pub mod crash_test; diff --git a/alloc/tests/vec.rs b/alloc/tests/vec.rs index 0f27fdff3e182..b24daec2968e0 100644 --- a/alloc/tests/vec.rs +++ b/alloc/tests/vec.rs @@ -1204,22 +1204,16 @@ fn test_from_iter_specialization_with_iterator_adapters() { #[test] fn test_in_place_specialization_step_up_down() { fn assert_in_place_trait(_: &T) {} - let src = vec![[0u8; 4]; 256]; - let srcptr = src.as_ptr(); - let src_cap = src.capacity(); - let iter = src.into_iter().flatten(); - assert_in_place_trait(&iter); - let sink = iter.collect::>(); - let sinkptr = sink.as_ptr(); - assert_eq!(srcptr as *const u8, sinkptr); - assert_eq!(src_cap * 4, sink.capacity()); - let iter = sink.into_iter().array_chunks::<4>(); + let src = vec![0u8; 1024]; + let srcptr = src.as_ptr(); + let src_bytes = src.capacity(); + let iter = src.into_iter().array_chunks::<4>(); assert_in_place_trait(&iter); let sink = iter.collect::>(); let sinkptr = sink.as_ptr(); - assert_eq!(srcptr, sinkptr); - assert_eq!(src_cap, sink.capacity()); + assert_eq!(srcptr.addr(), sinkptr.addr()); + assert_eq!(src_bytes, sink.capacity() * 4); let mut src: Vec = Vec::with_capacity(17); let src_bytes = src.capacity(); @@ -1236,13 +1230,6 @@ fn test_in_place_specialization_step_up_down() { let sink: Vec<[u8; 2]> = iter.collect(); assert_eq!(sink.len(), 8); assert!(sink.capacity() <= 25); - - let src = vec![[0u8; 4]; 256]; - let srcptr = src.as_ptr(); - let iter = src.into_iter().flat_map(|a| a.into_iter().map(|b| b.wrapping_add(1))); - assert_in_place_trait(&iter); - let sink = iter.collect::>(); - assert_eq!(srcptr as *const u8, sink.as_ptr()); } #[test] @@ -1350,6 +1337,20 @@ fn test_collect_after_iterator_clone() { assert_eq!(v, [1, 1, 1, 1, 1]); assert!(v.len() <= v.capacity()); } + +// regression test for #135103, similar to the one above Flatten/FlatMap had an unsound InPlaceIterable +// implementation. +#[test] +fn test_flatten_clone() { + const S: String = String::new(); + + let v = vec![[S, "Hello World!".into()], [S, S]]; + let mut i = v.into_iter().flatten(); + let _ = i.next(); + let result: Vec = i.clone().collect(); + assert_eq!(result, ["Hello World!", "", ""]); +} + #[test] fn test_cow_from() { let borrowed: &[_] = &["borrowed", "(slice)"]; @@ -1414,7 +1415,7 @@ fn extract_if_empty() { let mut vec: Vec = vec![]; { - let mut iter = vec.extract_if(|_| true); + let mut iter = vec.extract_if(.., |_| true); assert_eq!(iter.size_hint(), (0, Some(0))); assert_eq!(iter.next(), None); assert_eq!(iter.size_hint(), (0, Some(0))); @@ -1431,7 +1432,7 @@ fn extract_if_zst() { let initial_len = vec.len(); let mut count = 0; { - let mut iter = vec.extract_if(|_| true); + let mut iter = vec.extract_if(.., |_| true); assert_eq!(iter.size_hint(), (0, Some(initial_len))); while let Some(_) = iter.next() { count += 1; @@ -1454,7 +1455,7 @@ fn extract_if_false() { let initial_len = vec.len(); let mut count = 0; { - let mut iter = vec.extract_if(|_| false); + let mut iter = vec.extract_if(.., |_| false); assert_eq!(iter.size_hint(), (0, Some(initial_len))); for _ in iter.by_ref() { count += 1; @@ -1476,7 +1477,7 @@ fn extract_if_true() { let initial_len = vec.len(); let mut count = 0; { - let mut iter = vec.extract_if(|_| true); + let mut iter = vec.extract_if(.., |_| true); assert_eq!(iter.size_hint(), (0, Some(initial_len))); while let Some(_) = iter.next() { count += 1; @@ -1492,6 +1493,31 @@ fn extract_if_true() { assert_eq!(vec, vec![]); } +#[test] +fn extract_if_ranges() { + let mut vec = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + + let mut count = 0; + let it = vec.extract_if(1..=3, |_| { + count += 1; + true + }); + assert_eq!(it.collect::>(), vec![1, 2, 3]); + assert_eq!(vec, vec![0, 4, 5, 6, 7, 8, 9, 10]); + assert_eq!(count, 3); + + let it = vec.extract_if(1..=3, |_| false); + assert_eq!(it.collect::>(), vec![]); + assert_eq!(vec, vec![0, 4, 5, 6, 7, 8, 9, 10]); +} + +#[test] +#[should_panic] +fn extract_if_out_of_bounds() { + let mut vec = vec![0, 1]; + let _ = vec.extract_if(5.., |_| true).for_each(drop); +} + #[test] fn extract_if_complex() { { @@ -1501,7 +1527,7 @@ fn extract_if_complex() { 39, ]; - let removed = vec.extract_if(|x| *x % 2 == 0).collect::>(); + let removed = vec.extract_if(.., |x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]); @@ -1515,7 +1541,7 @@ fn extract_if_complex() { 2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36, 37, 39, ]; - let removed = vec.extract_if(|x| *x % 2 == 0).collect::>(); + let removed = vec.extract_if(.., |x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]); @@ -1528,7 +1554,7 @@ fn extract_if_complex() { let mut vec = vec![2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36]; - let removed = vec.extract_if(|x| *x % 2 == 0).collect::>(); + let removed = vec.extract_if(.., |x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]); @@ -1540,7 +1566,7 @@ fn extract_if_complex() { // [xxxxxxxxxx+++++++++++] let mut vec = vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]; - let removed = vec.extract_if(|x| *x % 2 == 0).collect::>(); + let removed = vec.extract_if(.., |x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); assert_eq!(removed, vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20]); @@ -1552,7 +1578,7 @@ fn extract_if_complex() { // [+++++++++++xxxxxxxxxx] let mut vec = vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]; - let removed = vec.extract_if(|x| *x % 2 == 0).collect::>(); + let removed = vec.extract_if(.., |x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); assert_eq!(removed, vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20]); @@ -1600,7 +1626,7 @@ fn extract_if_consumed_panic() { } c.index < 6 }; - let drain = data.extract_if(filter); + let drain = data.extract_if(.., filter); // NOTE: The ExtractIf is explicitly consumed drain.for_each(drop); @@ -1653,7 +1679,7 @@ fn extract_if_unconsumed_panic() { } c.index < 6 }; - let _drain = data.extract_if(filter); + let _drain = data.extract_if(.., filter); // NOTE: The ExtractIf is dropped without being consumed }); @@ -1669,7 +1695,7 @@ fn extract_if_unconsumed_panic() { #[test] fn extract_if_unconsumed() { let mut vec = vec![1, 2, 3, 4]; - let drain = vec.extract_if(|&mut x| x % 2 != 0); + let drain = vec.extract_if(.., |&mut x| x % 2 != 0); drop(drain); assert_eq!(vec, [1, 2, 3, 4]); } @@ -2716,3 +2742,13 @@ fn max_swap_remove() { let mut v = vec![0]; v.swap_remove(usize::MAX); } + +// Regression test for #135338 +#[test] +fn vec_null_ptr_roundtrip() { + let ptr = std::ptr::from_ref(&42); + let zero = ptr.with_addr(0); + let roundtripped = vec![zero; 1].pop().unwrap(); + let new = roundtripped.with_addr(ptr.addr()); + unsafe { new.read() }; +} diff --git a/backtrace b/backtrace index 230570f2dac80..f8cc6ac9acc4e 160000 --- a/backtrace +++ b/backtrace @@ -1 +1 @@ -Subproject commit 230570f2dac80a601f5c0b30da00cc9480bd35eb +Subproject commit f8cc6ac9acc4e663ecd96f9bcf1ff4542636d1b9 diff --git a/core/Cargo.toml b/core/Cargo.toml index 94f343d06705e..46c55c437cce5 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -43,8 +43,7 @@ check-cfg = [ 'cfg(bootstrap)', 'cfg(no_fp_fmt_parse)', 'cfg(stdarch_intel_sde)', - # #[cfg(bootstrap)] rtems - 'cfg(target_os, values("rtems"))', + 'cfg(target_arch, values("xtensa"))', # core use #[path] imports to portable-simd `core_simd` crate # and to stdarch `core_arch` crate which messes-up with Cargo list # of declared features, we therefor expect any feature cfg diff --git a/core/benches/ascii/is_ascii.rs b/core/benches/ascii/is_ascii.rs index 4b2920c5eb45f..ced7084fb0e48 100644 --- a/core/benches/ascii/is_ascii.rs +++ b/core/benches/ascii/is_ascii.rs @@ -10,9 +10,12 @@ macro_rules! benches { // Ensure we benchmark cases where the functions are called with strings // that are not perfectly aligned or have a length which is not a // multiple of size_of::() (or both) - benches!(mod unaligned_head MEDIUM[1..] $($name $arg $body)+); - benches!(mod unaligned_tail MEDIUM[..(MEDIUM.len() - 1)] $($name $arg $body)+); - benches!(mod unaligned_both MEDIUM[1..(MEDIUM.len() - 1)] $($name $arg $body)+); + benches!(mod unaligned_head_medium MEDIUM[1..] $($name $arg $body)+); + benches!(mod unaligned_tail_medium MEDIUM[..(MEDIUM.len() - 1)] $($name $arg $body)+); + benches!(mod unaligned_both_medium MEDIUM[1..(MEDIUM.len() - 1)] $($name $arg $body)+); + benches!(mod unaligned_head_long LONG[1..] $($name $arg $body)+); + benches!(mod unaligned_tail_long LONG[..(LONG.len() - 1)] $($name $arg $body)+); + benches!(mod unaligned_both_long LONG[1..(LONG.len() - 1)] $($name $arg $body)+); }; (mod $mod_name: ident $input: ident [$range: expr] $($name: ident $arg: ident $body: block)+) => { @@ -49,6 +52,44 @@ benches! { fn case03_align_to_unrolled(bytes: &[u8]) { is_ascii_align_to_unrolled(bytes) } + + fn case04_while_loop(bytes: &[u8]) { + // Process chunks of 32 bytes at a time in the fast path to enable + // auto-vectorization and use of `pmovmskb`. Two 128-bit vector registers + // can be OR'd together and then the resulting vector can be tested for + // non-ASCII bytes. + const CHUNK_SIZE: usize = 32; + + let mut i = 0; + + while i + CHUNK_SIZE <= bytes.len() { + let chunk_end = i + CHUNK_SIZE; + + // Get LLVM to produce a `pmovmskb` instruction on x86-64 which + // creates a mask from the most significant bit of each byte. + // ASCII bytes are less than 128 (0x80), so their most significant + // bit is unset. + let mut count = 0; + while i < chunk_end { + count += bytes[i].is_ascii() as u8; + i += 1; + } + + // All bytes should be <= 127 so count is equal to chunk size. + if count != CHUNK_SIZE as u8 { + return false; + } + } + + // Process the remaining `bytes.len() % N` bytes. + let mut is_ascii = true; + while i < bytes.len() { + is_ascii &= bytes[i].is_ascii(); + i += 1; + } + + is_ascii + } } // These are separate since it's easier to debug errors if they don't go through diff --git a/core/benches/num/int_pow/mod.rs b/core/benches/num/int_pow/mod.rs index 6cf9021358283..46f47028d56e6 100644 --- a/core/benches/num/int_pow/mod.rs +++ b/core/benches/num/int_pow/mod.rs @@ -25,7 +25,7 @@ macro_rules! pow_bench_template { let mut exp_iter = black_box(&exp_array).into_iter(); (0..ITERATIONS).fold((0 as IntType, false), |acc, _| { - // Sometimes constants don't propogate all the way to the + // Sometimes constants don't propagate all the way to the // inside of the loop, so we call a custom expression every cycle // rather than iter::repeat(CONST) let base: IntType = $base_macro!(base_iter); diff --git a/core/src/alloc/layout.rs b/core/src/alloc/layout.rs index f412ca1716338..17f4d68867e1e 100644 --- a/core/src/alloc/layout.rs +++ b/core/src/alloc/layout.rs @@ -157,7 +157,6 @@ impl Layout { #[must_use = "this returns the minimum alignment, \ without modifying the layout"] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(ptr_alignment_type))] pub const fn align(&self) -> usize { self.align.as_usize() } @@ -179,7 +178,7 @@ impl Layout { /// allocate backing structure for `T` (which could be a trait /// or other unsized type like a slice). #[stable(feature = "alloc_layout", since = "1.28.0")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] + #[rustc_const_stable(feature = "const_alloc_layout", since = "1.85.0")] #[must_use] #[inline] pub const fn for_value(t: &T) -> Self { @@ -216,7 +215,6 @@ impl Layout { /// [trait object]: ../../book/ch17-02-trait-objects.html /// [extern type]: ../../unstable-book/language-features/extern-types.html #[unstable(feature = "layout_for_ptr", issue = "69835")] - #[rustc_const_unstable(feature = "layout_for_ptr", issue = "69835")] #[must_use] pub const unsafe fn for_value_raw(t: *const T) -> Self { // SAFETY: we pass along the prerequisites of these functions to the caller @@ -235,8 +233,7 @@ impl Layout { #[must_use] #[inline] pub const fn dangling(&self) -> NonNull { - // SAFETY: align is guaranteed to be non-zero - unsafe { NonNull::new_unchecked(crate::ptr::without_provenance_mut::(self.align())) } + NonNull::without_provenance(self.align.as_nonzero()) } /// Creates a layout describing the record that can hold a value @@ -254,8 +251,7 @@ impl Layout { /// Returns an error if the combination of `self.size()` and the given /// `align` violates the conditions listed in [`Layout::from_size_align`]. #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] - #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] + #[rustc_const_stable(feature = "const_alloc_layout", since = "1.85.0")] #[inline] pub const fn align_to(&self, align: usize) -> Result { if let Some(align) = Alignment::new(align) { @@ -330,8 +326,7 @@ impl Layout { /// This is equivalent to adding the result of `padding_needed_for` /// to the layout's current size. #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] - #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] + #[rustc_const_stable(feature = "const_alloc_layout", since = "1.85.0")] #[must_use = "this returns a new `Layout`, \ without modifying the original"] #[inline] @@ -430,8 +425,7 @@ impl Layout { /// # assert_eq!(repr_c(&[u64, u32, u16, u32]), Ok((s, vec![0, 8, 12, 16]))); /// ``` #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] - #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] + #[rustc_const_stable(feature = "const_alloc_layout", since = "1.85.0")] #[inline] pub const fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> { let new_align = Alignment::max(self.align, next.align); @@ -494,8 +488,7 @@ impl Layout { /// On arithmetic overflow or when the total size would exceed /// `isize::MAX`, returns `LayoutError`. #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] - #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] + #[rustc_const_stable(feature = "const_alloc_layout", since = "1.85.0")] #[inline] pub const fn array(n: usize) -> Result { // Reduce the amount of code we need to monomorphize per `T`. diff --git a/core/src/any.rs b/core/src/any.rs index 58107b1e7d074..17d9455592787 100644 --- a/core/src/any.rs +++ b/core/src/any.rs @@ -423,7 +423,8 @@ impl dyn Any + Send { /// /// # Safety /// - /// Same as the method on the type `dyn Any`. + /// The contained value must be of type `T`. Calling this method + /// with the incorrect type is *undefined behavior*. #[unstable(feature = "downcast_unchecked", issue = "90850")] #[inline] pub unsafe fn downcast_ref_unchecked(&self) -> &T { @@ -451,7 +452,8 @@ impl dyn Any + Send { /// /// # Safety /// - /// Same as the method on the type `dyn Any`. + /// The contained value must be of type `T`. Calling this method + /// with the incorrect type is *undefined behavior*. #[unstable(feature = "downcast_unchecked", issue = "90850")] #[inline] pub unsafe fn downcast_mut_unchecked(&mut self) -> &mut T { @@ -552,6 +554,10 @@ impl dyn Any + Send + Sync { /// assert_eq!(*x.downcast_ref_unchecked::(), 1); /// } /// ``` + /// # Safety + /// + /// The contained value must be of type `T`. Calling this method + /// with the incorrect type is *undefined behavior*. #[unstable(feature = "downcast_unchecked", issue = "90850")] #[inline] pub unsafe fn downcast_ref_unchecked(&self) -> &T { @@ -576,6 +582,10 @@ impl dyn Any + Send + Sync { /// /// assert_eq!(*x.downcast_ref::().unwrap(), 2); /// ``` + /// # Safety + /// + /// The contained value must be of type `T`. Calling this method + /// with the incorrect type is *undefined behavior*. #[unstable(feature = "downcast_unchecked", issue = "90850")] #[inline] pub unsafe fn downcast_mut_unchecked(&mut self) -> &mut T { diff --git a/core/src/arch.rs b/core/src/arch.rs index 57f456c98b3c6..cb130f60cecf1 100644 --- a/core/src/arch.rs +++ b/core/src/arch.rs @@ -42,3 +42,29 @@ pub macro naked_asm("assembly template", $(operands,)* $(options($(option),*))?) pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))?) { /* compiler built-in */ } + +/// Compiles to a target-specific software breakpoint instruction or equivalent. +/// +/// This will typically abort the program. It may result in a core dump, and/or the system logging +/// debug information. Additional target-specific capabilities may be possible depending on +/// debuggers or other tooling; in particular, a debugger may be able to resume execution. +/// +/// If possible, this will produce an instruction sequence that allows a debugger to resume *after* +/// the breakpoint, rather than resuming *at* the breakpoint; however, the exact behavior is +/// target-specific and debugger-specific, and not guaranteed. +/// +/// If the target platform does not have any kind of debug breakpoint instruction, this may compile +/// to a trapping instruction (e.g. an undefined instruction) instead, or to some other form of +/// target-specific abort that may or may not support convenient resumption. +/// +/// The precise behavior and the precise instruction generated are not guaranteed, except that in +/// normal execution with no debug tooling involved this will not continue executing. +/// +/// - On x86 targets, this produces an `int3` instruction. +/// - On aarch64 targets, this produces a `brk #0xf000` instruction. +// When stabilizing this, update the comment on `core::intrinsics::breakpoint`. +#[unstable(feature = "breakpoint", issue = "133724")] +#[inline(always)] +pub fn breakpoint() { + core::intrinsics::breakpoint(); +} diff --git a/core/src/array/iter.rs b/core/src/array/iter.rs index 9ce0eb61e0814..1edade41597f7 100644 --- a/core/src/array/iter.rs +++ b/core/src/array/iter.rs @@ -214,7 +214,7 @@ impl IntoIter { // SAFETY: We know that all elements within `alive` are properly initialized. unsafe { let slice = self.data.get_unchecked(self.alive.clone()); - MaybeUninit::slice_assume_init_ref(slice) + slice.assume_init_ref() } } @@ -224,7 +224,7 @@ impl IntoIter { // SAFETY: We know that all elements within `alive` are properly initialized. unsafe { let slice = self.data.get_unchecked_mut(self.alive.clone()); - MaybeUninit::slice_assume_init_mut(slice) + slice.assume_init_mut() } } } @@ -285,7 +285,7 @@ impl Iterator for IntoIter { // SAFETY: These elements are currently initialized, so it's fine to drop them. unsafe { let slice = self.data.get_unchecked_mut(range_to_drop); - ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice)); + slice.assume_init_drop(); } NonZero::new(remaining).map_or(Ok(()), Err) @@ -340,7 +340,7 @@ impl DoubleEndedIterator for IntoIter { // SAFETY: These elements are currently initialized, so it's fine to drop them. unsafe { let slice = self.data.get_unchecked_mut(range_to_drop); - ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice)); + slice.assume_init_drop(); } NonZero::new(remaining).map_or(Ok(()), Err) diff --git a/core/src/array/mod.rs b/core/src/array/mod.rs index 67fbda34bb935..2ae5ded1fd55b 100644 --- a/core/src/array/mod.rs +++ b/core/src/array/mod.rs @@ -214,8 +214,8 @@ impl BorrowMut<[T]> for [T; N] { } } -/// Tries to create an array `[T; N]` by copying from a slice `&[T]`. Succeeds if -/// `slice.len() == N`. +/// Tries to create an array `[T; N]` by copying from a slice `&[T]`. +/// Succeeds if `slice.len() == N`. /// /// ``` /// let bytes: [u8; 3] = [1, 0, 2]; @@ -282,13 +282,7 @@ impl<'a, T, const N: usize> TryFrom<&'a [T]> for &'a [T; N] { #[inline] fn try_from(slice: &'a [T]) -> Result<&'a [T; N], TryFromSliceError> { - if slice.len() == N { - let ptr = slice.as_ptr() as *const [T; N]; - // SAFETY: ok because we just checked that the length fits - unsafe { Ok(&*ptr) } - } else { - Err(TryFromSliceError(())) - } + slice.as_array().ok_or(TryFromSliceError(())) } } @@ -310,13 +304,7 @@ impl<'a, T, const N: usize> TryFrom<&'a mut [T]> for &'a mut [T; N] { #[inline] fn try_from(slice: &'a mut [T]) -> Result<&'a mut [T; N], TryFromSliceError> { - if slice.len() == N { - let ptr = slice.as_mut_ptr() as *mut [T; N]; - // SAFETY: ok because we just checked that the length fits - unsafe { Ok(&mut *ptr) } - } else { - Err(TryFromSliceError(())) - } + slice.as_mut_array().ok_or(TryFromSliceError(())) } } @@ -923,9 +911,7 @@ impl Drop for Guard<'_, T> { // SAFETY: this slice will contain only initialized objects. unsafe { - crate::ptr::drop_in_place(MaybeUninit::slice_assume_init_mut( - self.array_mut.get_unchecked_mut(..self.initialized), - )); + self.array_mut.get_unchecked_mut(..self.initialized).assume_init_drop(); } } } diff --git a/core/src/bool.rs b/core/src/bool.rs index 58a870d2e0725..3c589ca5dfa7e 100644 --- a/core/src/bool.rs +++ b/core/src/bool.rs @@ -54,10 +54,59 @@ impl bool { /// // `then`. /// assert_eq!(a, 1); /// ``` + #[doc(alias = "then_with")] #[stable(feature = "lazy_bool_to_option", since = "1.50.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "bool_then")] #[inline] pub fn then T>(self, f: F) -> Option { if self { Some(f()) } else { None } } + + /// Returns either `true_val` or `false_val` depending on the value of + /// `self`, with a hint to the compiler that `self` is unlikely + /// to be correctly predicted by a CPU’s branch predictor. + /// + /// This method is functionally equivalent to + /// ```ignore (this is just for illustrative purposes) + /// fn select_unpredictable(b: bool, true_val: T, false_val: T) -> T { + /// if b { true_val } else { false_val } + /// } + /// ``` + /// but might generate different assembly. In particular, on platforms with + /// a conditional move or select instruction (like `cmov` on x86 or `csel` + /// on ARM) the optimizer might use these instructions to avoid branches, + /// which can benefit performance if the branch predictor is struggling + /// with predicting `condition`, such as in an implementation of binary + /// search. + /// + /// Note however that this lowering is not guaranteed (on any platform) and + /// should not be relied upon when trying to write constant-time code. Also + /// be aware that this lowering might *decrease* performance if `condition` + /// is well-predictable. It is advisable to perform benchmarks to tell if + /// this function is useful. + /// + /// # Examples + /// + /// Distribute values evenly between two buckets: + /// ``` + /// #![feature(select_unpredictable)] + /// + /// use std::hash::BuildHasher; + /// + /// fn append(hasher: &H, v: i32, bucket_one: &mut Vec, bucket_two: &mut Vec) { + /// let hash = hasher.hash_one(&v); + /// let bucket = (hash % 2 == 0).select_unpredictable(bucket_one, bucket_two); + /// bucket.push(v); + /// } + /// # let hasher = std::collections::hash_map::RandomState::new(); + /// # let mut bucket_one = Vec::new(); + /// # let mut bucket_two = Vec::new(); + /// # append(&hasher, 42, &mut bucket_one, &mut bucket_two); + /// # assert_eq!(bucket_one.len() + bucket_two.len(), 1); + /// ``` + #[inline(always)] + #[unstable(feature = "select_unpredictable", issue = "133962")] + pub fn select_unpredictable(self, true_val: T, false_val: T) -> T { + crate::intrinsics::select_unpredictable(self, true_val, false_val) + } } diff --git a/core/src/cell.rs b/core/src/cell.rs index bfd2a71f97b2c..306d565a77e66 100644 --- a/core/src/cell.rs +++ b/core/src/cell.rs @@ -252,7 +252,7 @@ use crate::cmp::Ordering; use crate::fmt::{self, Debug, Display}; -use crate::marker::{PhantomData, Unsize}; +use crate::marker::{PhantomData, PointerLike, Unsize}; use crate::mem; use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn}; use crate::pin::PinCoerceUnsized; @@ -587,7 +587,7 @@ impl Cell { #[inline] #[stable(feature = "cell_as_ptr", since = "1.12.0")] #[rustc_const_stable(feature = "const_cell_as_ptr", since = "1.32.0")] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[rustc_never_returns_null_ptr] pub const fn as_ptr(&self) -> *mut T { self.value.get() @@ -677,6 +677,9 @@ impl, U> CoerceUnsized> for Cell {} #[unstable(feature = "dispatch_from_dyn", issue = "none")] impl, U> DispatchFromDyn> for Cell {} +#[unstable(feature = "pointer_like_trait", issue = "none")] +impl PointerLike for Cell {} + impl Cell<[T]> { /// Returns a `&[Cell]` from a `&Cell<[T]>` /// @@ -713,7 +716,6 @@ impl Cell<[T; N]> { /// let array_cell: &[Cell; 3] = cell_array.as_array_of_cells(); /// ``` #[unstable(feature = "as_array_of_cells", issue = "88248")] - #[rustc_const_unstable(feature = "as_array_of_cells", issue = "88248")] pub const fn as_array_of_cells(&self) -> &[Cell; N] { // SAFETY: `Cell` has the same memory layout as `T`. unsafe { &*(self as *const Cell<[T; N]> as *const [Cell; N]) } @@ -1150,7 +1152,7 @@ impl RefCell { /// ``` #[inline] #[stable(feature = "cell_as_ptr", since = "1.12.0")] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[rustc_never_returns_null_ptr] pub fn as_ptr(&self) -> *mut T { self.value.get() @@ -2133,9 +2135,8 @@ impl UnsafeCell { /// assert_eq!(*uc.get_mut(), 41); /// ``` #[inline(always)] - #[stable(feature = "unsafe_cell_from_mut", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unsafe_cell_from_mut", since = "CURRENT_RUSTC_VERSION")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] + #[stable(feature = "unsafe_cell_from_mut", since = "1.84.0")] + #[rustc_const_stable(feature = "unsafe_cell_from_mut", since = "1.84.0")] pub const fn from_mut(value: &mut T) -> &mut UnsafeCell { // SAFETY: `UnsafeCell` has the same memory layout as `T` due to #[repr(transparent)]. unsafe { &mut *(value as *mut T as *mut UnsafeCell) } @@ -2160,7 +2161,7 @@ impl UnsafeCell { #[inline(always)] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_unsafecell_get", since = "1.32.0")] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[rustc_never_returns_null_ptr] pub const fn get(&self) -> *mut T { // We can just cast the pointer from `UnsafeCell` to `T` because of @@ -2260,6 +2261,9 @@ impl, U> CoerceUnsized> for UnsafeCell {} #[unstable(feature = "dispatch_from_dyn", issue = "none")] impl, U> DispatchFromDyn> for UnsafeCell {} +#[unstable(feature = "pointer_like_trait", issue = "none")] +impl PointerLike for UnsafeCell {} + /// [`UnsafeCell`], but [`Sync`]. /// /// This is just an `UnsafeCell`, except it implements `Sync` @@ -2308,7 +2312,7 @@ impl SyncUnsafeCell { /// when casting to `&mut T`, and ensure that there are no mutations /// or mutable aliases going on when casting to `&T` #[inline] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[rustc_never_returns_null_ptr] pub const fn get(&self) -> *mut T { self.value.get() @@ -2366,6 +2370,9 @@ impl, U> CoerceUnsized> for SyncUnsafeCell //#[unstable(feature = "sync_unsafe_cell", issue = "95439")] impl, U> DispatchFromDyn> for SyncUnsafeCell {} +#[unstable(feature = "pointer_like_trait", issue = "none")] +impl PointerLike for SyncUnsafeCell {} + #[allow(unused)] fn assert_coerce_unsized( a: UnsafeCell<&i32>, diff --git a/core/src/cell/lazy.rs b/core/src/cell/lazy.rs index 5ac33516684d7..84cbbc71f40ae 100644 --- a/core/src/cell/lazy.rs +++ b/core/src/cell/lazy.rs @@ -219,7 +219,7 @@ impl T> LazyCell { } impl LazyCell { - /// Returns a reference to the value if initialized, or `None` if not. + /// Returns a mutable reference to the value if initialized, or `None` if not. /// /// # Examples /// @@ -245,7 +245,7 @@ impl LazyCell { } } - /// Returns a mutable reference to the value if initialized, or `None` if not. + /// Returns a reference to the value if initialized, or `None` if not. /// /// # Examples /// diff --git a/core/src/cell/once.rs b/core/src/cell/once.rs index c14afe0f4761c..6a85791916a61 100644 --- a/core/src/cell/once.rs +++ b/core/src/cell/once.rs @@ -262,7 +262,9 @@ impl OnceCell { /// /// let value = cell.get_mut_or_try_init(|| "1234".parse()); /// assert_eq!(value, Ok(&mut 1234)); - /// *value.unwrap() += 2; + /// + /// let Ok(value) = value else { return; }; + /// *value += 2; /// assert_eq!(cell.get(), Some(&1236)) /// ``` #[unstable(feature = "once_cell_get_mut", issue = "121641")] @@ -304,8 +306,8 @@ impl OnceCell { /// assert_eq!(cell.into_inner(), None); /// /// let cell = OnceCell::new(); - /// cell.set("hello".to_string()).unwrap(); - /// assert_eq!(cell.into_inner(), Some("hello".to_string())); + /// let _ = cell.set("hello".to_owned()); + /// assert_eq!(cell.into_inner(), Some("hello".to_owned())); /// ``` #[inline] #[stable(feature = "once_cell", since = "1.70.0")] @@ -332,8 +334,8 @@ impl OnceCell { /// assert_eq!(cell.take(), None); /// /// let mut cell = OnceCell::new(); - /// cell.set("hello".to_string()).unwrap(); - /// assert_eq!(cell.take(), Some("hello".to_string())); + /// let _ = cell.set("hello".to_owned()); + /// assert_eq!(cell.take(), Some("hello".to_owned())); /// assert_eq!(cell.get(), None); /// ``` #[inline] diff --git a/core/src/char/methods.rs b/core/src/char/methods.rs index 974e7baccf7bc..fb8a740aced13 100644 --- a/core/src/char/methods.rs +++ b/core/src/char/methods.rs @@ -394,17 +394,21 @@ impl char { ); // check radix to remove letter handling code when radix is a known constant let value = if self > '9' && radix > 10 { - // convert ASCII letters to lowercase - let lower = self as u32 | 0x20; - // convert an ASCII letter to the corresponding value, - // non-letters convert to values > 36 - lower.wrapping_sub('a' as u32) as u64 + 10 + // mask to convert ASCII letters to uppercase + const TO_UPPERCASE_MASK: u32 = !0b0010_0000; + // Converts an ASCII letter to its corresponding integer value: + // A-Z => 10-35, a-z => 10-35. Other characters produce values >= 36. + // + // Add Overflow Safety: + // By applying the mask after the subtraction, the first addendum is + // constrained such that it never exceeds u32::MAX - 0x20. + ((self as u32).wrapping_sub('A' as u32) & TO_UPPERCASE_MASK) + 10 } else { // convert digit to value, non-digits wrap to values > 36 - (self as u32).wrapping_sub('0' as u32) as u64 + (self as u32).wrapping_sub('0' as u32) }; // FIXME(const-hack): once then_some is const fn, use it here - if value < radix as u64 { Some(value as u32) } else { None } + if value < radix { Some(value) } else { None } } /// Returns an iterator that yields the hexadecimal Unicode escape of a @@ -729,7 +733,7 @@ impl char { /// '𝕊'.encode_utf16(&mut b); /// ``` #[stable(feature = "unicode_encode_char", since = "1.15.0")] - #[rustc_const_stable(feature = "const_char_encode_utf16", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_char_encode_utf16", since = "1.84.0")] #[inline] pub const fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] { encode_utf16_raw(self as u32, dst) @@ -1299,7 +1303,7 @@ impl char { /// /// [`to_ascii_uppercase()`]: #method.to_ascii_uppercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")] #[inline] pub const fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); @@ -1325,7 +1329,7 @@ impl char { /// /// [`to_ascii_lowercase()`]: #method.to_ascii_lowercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")] #[inline] pub const fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); @@ -1787,7 +1791,6 @@ const fn len_utf16(code: u32) -> usize { /// Panics if the buffer is not large enough. /// A buffer of length four is large enough to encode any `char`. #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_char_encode_utf8", since = "1.83.0"))] #[doc(hidden)] #[inline] pub const fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] { @@ -1836,10 +1839,6 @@ pub const fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] { /// Panics if the buffer is not large enough. /// A buffer of length 2 is large enough to encode any `char`. #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")] -#[cfg_attr( - bootstrap, - rustc_const_stable(feature = "const_char_encode_utf16", since = "CURRENT_RUSTC_VERSION") -)] #[doc(hidden)] #[inline] pub const fn encode_utf16_raw(mut code: u32, dst: &mut [u16]) -> &mut [u16] { diff --git a/core/src/cmp.rs b/core/src/cmp.rs index 5a3b9365cd220..97974d195fec6 100644 --- a/core/src/cmp.rs +++ b/core/src/cmp.rs @@ -796,7 +796,7 @@ impl Clone for Reverse { /// } /// /// impl Ord for Character { -/// fn cmp(&self, other: &Self) -> std::cmp::Ordering { +/// fn cmp(&self, other: &Self) -> Ordering { /// self.experience /// .cmp(&other.experience) /// .then(self.health.cmp(&other.health)) diff --git a/core/src/convert/mod.rs b/core/src/convert/mod.rs index 432e55e8c9a4c..e468f4f0f7e66 100644 --- a/core/src/convert/mod.rs +++ b/core/src/convert/mod.rs @@ -443,6 +443,7 @@ pub trait AsMut { /// [`Vec`]: ../../std/vec/struct.Vec.html #[rustc_diagnostic_item = "Into"] #[stable(feature = "rust1", since = "1.0.0")] +#[doc(search_unbox)] pub trait Into: Sized { /// Converts this type into the (usually inferred) input type. #[must_use] @@ -577,6 +578,7 @@ pub trait Into: Sized { all(_Self = "&str", T = "alloc::string::String"), note = "to coerce a `{T}` into a `{Self}`, use `&*` as a prefix", ))] +#[doc(search_unbox)] pub trait From: Sized { /// Converts to this type from the input type. #[rustc_diagnostic_item = "from_fn"] diff --git a/core/src/error.rs b/core/src/error.rs index 95a39cc3aed38..9dbea57fa1f86 100644 --- a/core/src/error.rs +++ b/core/src/error.rs @@ -2,7 +2,7 @@ #![stable(feature = "error_in_core", since = "1.81.0")] use crate::any::TypeId; -use crate::fmt::{Debug, Display, Formatter, Result}; +use crate::fmt::{self, Debug, Display, Formatter}; /// `Error` is a trait representing the basic expectations for error values, /// i.e., values of type `E` in [`Result`]. @@ -857,7 +857,7 @@ impl<'a> Request<'a> { #[unstable(feature = "error_generic_member_access", issue = "99301")] impl<'a> Debug for Request<'a> { - fn fmt(&self, f: &mut Formatter<'_>) -> Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_struct("Request").finish_non_exhaustive() } } @@ -1076,4 +1076,4 @@ impl Error for crate::time::TryFromFloatSecsError {} impl Error for crate::ffi::FromBytesUntilNulError {} #[unstable(feature = "get_many_mut", issue = "104642")] -impl Error for crate::slice::GetManyMutError {} +impl Error for crate::slice::GetManyMutError {} diff --git a/core/src/ffi/c_str.rs b/core/src/ffi/c_str.rs index 9e32f74227cf9..7180593edf0d0 100644 --- a/core/src/ffi/c_str.rs +++ b/core/src/ffi/c_str.rs @@ -124,39 +124,25 @@ pub struct CStr { /// /// let _: FromBytesWithNulError = CStr::from_bytes_with_nul(b"f\0oo").unwrap_err(); /// ``` -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] #[stable(feature = "core_c_str", since = "1.64.0")] -pub struct FromBytesWithNulError { - kind: FromBytesWithNulErrorKind, -} - -#[derive(Clone, PartialEq, Eq, Debug)] -enum FromBytesWithNulErrorKind { - InteriorNul(usize), +pub enum FromBytesWithNulError { + /// Data provided contains an interior nul byte at byte `position`. + InteriorNul { + /// The position of the interior nul byte. + position: usize, + }, + /// Data provided is not nul terminated. NotNulTerminated, } -// FIXME: const stability attributes should not be required here, I think -impl FromBytesWithNulError { - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cstr_methods", since = "1.72.0"))] - const fn interior_nul(pos: usize) -> FromBytesWithNulError { - FromBytesWithNulError { kind: FromBytesWithNulErrorKind::InteriorNul(pos) } - } - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cstr_methods", since = "1.72.0"))] - const fn not_nul_terminated() -> FromBytesWithNulError { - FromBytesWithNulError { kind: FromBytesWithNulErrorKind::NotNulTerminated } - } -} - #[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")] impl Error for FromBytesWithNulError { #[allow(deprecated)] fn description(&self) -> &str { - match self.kind { - FromBytesWithNulErrorKind::InteriorNul(..) => { - "data provided contains an interior nul byte" - } - FromBytesWithNulErrorKind::NotNulTerminated => "data provided is not nul terminated", + match self { + Self::InteriorNul { .. } => "data provided contains an interior nul byte", + Self::NotNulTerminated => "data provided is not nul terminated", } } } @@ -201,8 +187,8 @@ impl fmt::Display for FromBytesWithNulError { #[allow(deprecated, deprecated_in_future)] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(self.description())?; - if let FromBytesWithNulErrorKind::InteriorNul(pos) = self.kind { - write!(f, " at byte pos {pos}")?; + if let Self::InteriorNul { position } = self { + write!(f, " at byte pos {position}")?; } Ok(()) } @@ -351,25 +337,25 @@ impl CStr { /// use std::ffi::CStr; /// /// let cstr = CStr::from_bytes_with_nul(b"hello\0"); - /// assert!(cstr.is_ok()); + /// assert_eq!(cstr, Ok(c"hello")); /// ``` /// /// Creating a `CStr` without a trailing nul terminator is an error: /// /// ``` - /// use std::ffi::CStr; + /// use std::ffi::{CStr, FromBytesWithNulError}; /// /// let cstr = CStr::from_bytes_with_nul(b"hello"); - /// assert!(cstr.is_err()); + /// assert_eq!(cstr, Err(FromBytesWithNulError::NotNulTerminated)); /// ``` /// /// Creating a `CStr` with an interior nul byte is an error: /// /// ``` - /// use std::ffi::CStr; + /// use std::ffi::{CStr, FromBytesWithNulError}; /// /// let cstr = CStr::from_bytes_with_nul(b"he\0llo\0"); - /// assert!(cstr.is_err()); + /// assert_eq!(cstr, Err(FromBytesWithNulError::InteriorNul { position: 2 })); /// ``` #[stable(feature = "cstr_from_bytes", since = "1.10.0")] #[rustc_const_stable(feature = "const_cstr_methods", since = "1.72.0")] @@ -381,8 +367,8 @@ impl CStr { // of the byte slice. Ok(unsafe { Self::from_bytes_with_nul_unchecked(bytes) }) } - Some(nul_pos) => Err(FromBytesWithNulError::interior_nul(nul_pos)), - None => Err(FromBytesWithNulError::not_nul_terminated()), + Some(position) => Err(FromBytesWithNulError::InteriorNul { position }), + None => Err(FromBytesWithNulError::NotNulTerminated), } } @@ -464,8 +450,7 @@ impl CStr { /// /// ```no_run /// # #![allow(unused_must_use)] - /// # #![cfg_attr(bootstrap, expect(temporary_cstring_as_ptr))] - /// # #![cfg_attr(not(bootstrap), expect(dangling_pointers_from_temporaries))] + /// # #![expect(dangling_pointers_from_temporaries)] /// use std::ffi::CString; /// /// // Do not do this: @@ -500,7 +485,7 @@ impl CStr { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_str_as_ptr", since = "1.32.0")] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[rustc_never_returns_null_ptr] pub const fn as_ptr(&self) -> *const c_char { self.inner.as_ptr() @@ -732,7 +717,6 @@ impl AsRef for CStr { /// located within `isize::MAX` from `ptr`. #[inline] #[unstable(feature = "cstr_internals", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cstr_from_ptr", since = "1.81.0"))] #[rustc_allow_const_fn_unstable(const_eval_select)] const unsafe fn strlen(ptr: *const c_char) -> usize { const_eval_select!( diff --git a/core/src/ffi/mod.rs b/core/src/ffi/mod.rs index dc107c5d22cdd..5f32775822be6 100644 --- a/core/src/ffi/mod.rs +++ b/core/src/ffi/mod.rs @@ -12,10 +12,10 @@ #[doc(inline)] #[stable(feature = "core_c_str", since = "1.64.0")] pub use self::c_str::CStr; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")] pub use self::c_str::FromBytesUntilNulError; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "core_c_str", since = "1.64.0")] pub use self::c_str::FromBytesWithNulError; use crate::fmt; @@ -91,59 +91,86 @@ pub type c_ssize_t = isize; mod c_char_definition { cfg_if! { - // These are the targets on which c_char is unsigned. - if #[cfg(any( - all( - target_os = "linux", - any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "hexagon", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "s390x", - target_arch = "riscv64", - target_arch = "riscv32", - target_arch = "csky" - ) - ), - all(target_os = "android", any(target_arch = "aarch64", target_arch = "arm")), - all(target_os = "l4re", target_arch = "x86_64"), - all( - any(target_os = "freebsd", target_os = "openbsd", target_os = "rtems"), - any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "riscv64" - ) - ), - all( - target_os = "netbsd", - any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "powerpc", - target_arch = "riscv64" - ) - ), - all( - target_os = "vxworks", - any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "powerpc64", - target_arch = "powerpc" - ) - ), - all( - target_os = "fuchsia", - any(target_arch = "aarch64", target_arch = "riscv64") - ), - all(target_os = "nto", target_arch = "aarch64"), - target_os = "horizon", - target_os = "aix", + // These are the targets on which c_char is unsigned. Usually the + // signedness is the same for all target_os values on a given architecture + // but there are some exceptions (see isSignedCharDefault() in clang). + // + // aarch64: + // Section 10 "Arm C and C++ language mappings" in Procedure Call Standard for the Arm® + // 64-bit Architecture (AArch64) says C/C++ char is unsigned byte. + // https://github.com/ARM-software/abi-aa/blob/2024Q3/aapcs64/aapcs64.rst#arm-c-and-c-language-mappings + // arm: + // Section 8 "Arm C and C++ Language Mappings" in Procedure Call Standard for the Arm® + // Architecture says C/C++ char is unsigned byte. + // https://github.com/ARM-software/abi-aa/blob/2024Q3/aapcs32/aapcs32.rst#arm-c-and-c-language-mappings + // csky: + // Section 2.1.2 "Primary Data Type" in C-SKY V2 CPU Applications Binary Interface + // Standards Manual says ANSI C char is unsigned byte. + // https://github.com/c-sky/csky-doc/blob/9f7121f7d40970ba5cc0f15716da033db2bb9d07/C-SKY_V2_CPU_Applications_Binary_Interface_Standards_Manual.pdf + // Note: this doesn't seem to match Clang's default (https://github.com/rust-lang/rust/issues/129945). + // hexagon: + // Section 3.1 "Basic data type" in Qualcomm Hexagon™ Application + // Binary Interface User Guide says "By default, the `char` data type is unsigned." + // https://docs.qualcomm.com/bundle/publicresource/80-N2040-23_REV_K_Qualcomm_Hexagon_Application_Binary_Interface_User_Guide.pdf + // msp430: + // Section 2.1 "Basic Types" in MSP430 Embedded Application Binary + // Interface says "The char type is unsigned by default". + // https://www.ti.com/lit/an/slaa534a/slaa534a.pdf + // Note: this doesn't seem to match Clang's default (https://github.com/rust-lang/rust/issues/129945). + // powerpc/powerpc64: + // - PPC32 SysV: "Table 3-1 Scalar Types" in System V Application Binary Interface PowerPC + // Processor Supplement says ANSI C char is unsigned byte + // https://refspecs.linuxfoundation.org/elf/elfspec_ppc.pdf + // - PPC64 ELFv1: Section 3.1.4 "Fundamental Types" in 64-bit PowerPC ELF Application + // Binary Interface Supplement 1.9 says ANSI C is unsigned byte + // https://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#FUND-TYPE + // - PPC64 ELFv2: Section 2.1.2.2 "Fundamental Types" in 64-Bit ELF V2 ABI Specification + // says char is unsigned byte + // https://openpowerfoundation.org/specifications/64bitelfabi/ + // - AIX: XL C for AIX Language Reference says "By default, char behaves like an unsigned char." + // https://www.ibm.com/docs/en/xl-c-aix/13.1.3?topic=specifiers-character-types + // riscv32/riscv64: + // C/C++ type representations section in RISC-V Calling Conventions + // page in RISC-V ELF psABI Document says "char is unsigned." + // https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/draft-20240829-13bfa9f54634cb60d86b9b333e109f077805b4b3/riscv-cc.adoc#cc-type-representations + // s390x: + // - ELF: "Table 1.1.: Scalar types" in ELF Application Binary Interface s390x Supplement + // Version 1.6.1 categorize ISO C char in unsigned integer + // https://github.com/IBM/s390x-abi/releases/tag/v1.6.1 + // - z/OS: XL C/C++ Language Reference says: "By default, char behaves like an unsigned char." + // https://www.ibm.com/docs/en/zos/3.1.0?topic=specifiers-character-types + // Xtensa: + // - "The char type is unsigned by default for Xtensa processors." + // + // On the following operating systems, c_char is signed by default, regardless of architecture. + // Darwin (macOS, iOS, etc.): + // Apple targets' c_char is signed by default even on arm + // https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Handle-data-types-and-data-alignment-properly + // Windows: + // Windows MSVC C++ Language Reference says "Microsoft-specific: Variables of type char + // are promoted to int as if from type signed char by default, unless the /J compilation + // option is used." + // https://learn.microsoft.com/en-us/cpp/cpp/fundamental-types-cpp?view=msvc-170#character-types) + // L4RE: + // The kernel builds with -funsigned-char on all targets (but useserspace follows the + // architecture defaults). As we only have a target for userspace apps so there are no + // special cases for L4RE below. + if #[cfg(all( + not(windows), + not(target_vendor = "apple"), + any( + target_arch = "aarch64", + target_arch = "arm", + target_arch = "csky", + target_arch = "hexagon", + target_arch = "msp430", + target_arch = "powerpc", + target_arch = "powerpc64", + target_arch = "riscv64", + target_arch = "riscv32", + target_arch = "s390x", + target_arch = "xtensa", + ) ))] { pub type c_char = u8; } else { diff --git a/core/src/ffi/va_list.rs b/core/src/ffi/va_list.rs index 3a224e4d8fe5f..f67c592d8d8f7 100644 --- a/core/src/ffi/va_list.rs +++ b/core/src/ffi/va_list.rs @@ -15,6 +15,7 @@ use crate::ops::{Deref, DerefMut}; not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "s390x"), + not(target_arch = "xtensa"), not(target_arch = "x86_64") ), all(target_arch = "aarch64", target_vendor = "apple"), @@ -37,6 +38,7 @@ pub struct VaListImpl<'f> { not(target_arch = "aarch64"), not(target_arch = "powerpc"), not(target_arch = "s390x"), + not(target_arch = "xtensa"), not(target_arch = "x86_64") ), all(target_arch = "aarch64", target_vendor = "apple"), @@ -113,6 +115,18 @@ pub struct VaListImpl<'f> { _marker: PhantomData<&'f mut &'f c_void>, } +/// Xtensa ABI implementation of a `va_list`. +#[cfg(target_arch = "xtensa")] +#[repr(C)] +#[derive(Debug)] +#[lang = "va_list"] +pub struct VaListImpl<'f> { + stk: *mut i32, + reg: *mut i32, + ndx: i32, + _marker: PhantomData<&'f mut &'f c_void>, +} + /// A wrapper for a `va_list` #[repr(transparent)] #[derive(Debug)] @@ -124,6 +138,7 @@ pub struct VaList<'a, 'f: 'a> { not(target_arch = "s390x"), not(target_arch = "x86_64") ), + target_arch = "xtensa", all(target_arch = "aarch64", target_vendor = "apple"), target_family = "wasm", target_os = "uefi", @@ -138,6 +153,7 @@ pub struct VaList<'a, 'f: 'a> { target_arch = "s390x", target_arch = "x86_64" ), + not(target_arch = "xtensa"), any(not(target_arch = "aarch64"), not(target_vendor = "apple")), not(target_family = "wasm"), not(target_os = "uefi"), @@ -155,6 +171,7 @@ pub struct VaList<'a, 'f: 'a> { not(target_arch = "s390x"), not(target_arch = "x86_64") ), + target_arch = "xtensa", all(target_arch = "aarch64", target_vendor = "apple"), target_family = "wasm", target_os = "uefi", @@ -173,8 +190,10 @@ impl<'f> VaListImpl<'f> { target_arch = "aarch64", target_arch = "powerpc", target_arch = "s390x", + target_arch = "xtensa", target_arch = "x86_64" ), + not(target_arch = "xtensa"), any(not(target_arch = "aarch64"), not(target_vendor = "apple")), not(target_family = "wasm"), not(target_os = "uefi"), diff --git a/core/src/fmt/float.rs b/core/src/fmt/float.rs index 04230b1610aae..3f10158193d76 100644 --- a/core/src/fmt/float.rs +++ b/core/src/fmt/float.rs @@ -86,7 +86,7 @@ where true => flt2dec::Sign::MinusPlus, }; - if let Some(precision) = fmt.precision { + if let Some(precision) = fmt.options.precision { float_to_decimal_common_exact(fmt, num, sign, precision) } else { let min_precision = 0; @@ -162,7 +162,7 @@ where true => flt2dec::Sign::MinusPlus, }; - if let Some(precision) = fmt.precision { + if let Some(precision) = fmt.options.precision { // 1 integral digit + `precision` fractional digits = `precision + 1` total digits float_to_exponential_common_exact(fmt, num, sign, precision + 1, upper) } else { @@ -180,7 +180,7 @@ where true => flt2dec::Sign::MinusPlus, }; - if let Some(precision) = fmt.precision { + if let Some(precision) = fmt.options.precision { // this behavior of {:.PREC?} predates exponential formatting for {:?} float_to_decimal_common_exact(fmt, num, sign, precision) } else { diff --git a/core/src/fmt/mod.rs b/core/src/fmt/mod.rs index 2b1692a195e50..a033b8bd30514 100644 --- a/core/src/fmt/mod.rs +++ b/core/src/fmt/mod.rs @@ -33,6 +33,19 @@ pub enum Alignment { Center, } +#[doc(hidden)] +#[unstable(feature = "fmt_internals", reason = "internal to standard library", issue = "none")] +impl From for Option { + fn from(value: rt::Alignment) -> Self { + match value { + rt::Alignment::Left => Some(Alignment::Left), + rt::Alignment::Right => Some(Alignment::Right), + rt::Alignment::Center => Some(Alignment::Center), + rt::Alignment::Unknown => None, + } + } +} + #[stable(feature = "debug_builders", since = "1.2.0")] pub use self::builders::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple}; #[unstable(feature = "debug_closure_helpers", issue = "117729")] @@ -139,8 +152,9 @@ pub trait Write { /// } /// /// let mut buf = String::new(); - /// writer(&mut buf, "hola").unwrap(); + /// writer(&mut buf, "hola")?; /// assert_eq!(&buf, "hola"); + /// # std::fmt::Result::Ok(()) /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn write_str(&mut self, s: &str) -> Result; @@ -166,9 +180,10 @@ pub trait Write { /// } /// /// let mut buf = String::new(); - /// writer(&mut buf, 'a').unwrap(); - /// writer(&mut buf, 'b').unwrap(); + /// writer(&mut buf, 'a')?; + /// writer(&mut buf, 'b')?; /// assert_eq!(&buf, "ab"); + /// # std::fmt::Result::Ok(()) /// ``` #[stable(feature = "fmt_write_char", since = "1.1.0")] fn write_char(&mut self, c: char) -> Result { @@ -195,8 +210,9 @@ pub trait Write { /// } /// /// let mut buf = String::new(); - /// writer(&mut buf, "world").unwrap(); + /// writer(&mut buf, "world")?; /// assert_eq!(&buf, "world"); + /// # std::fmt::Result::Ok(()) /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn write_fmt(&mut self, args: Arguments<'_>) -> Result { @@ -247,6 +263,251 @@ impl Write for &mut W { } } +/// The signedness of a [`Formatter`] (or of a [`FormattingOptions`]). +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[unstable(feature = "formatting_options", issue = "118117")] +pub enum Sign { + /// Represents the `+` flag. + Plus, + /// Represents the `-` flag. + Minus, +} + +/// Specifies whether the [`Debug`] trait should use lower-/upper-case +/// hexadecimal or normal integers. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[unstable(feature = "formatting_options", issue = "118117")] +pub enum DebugAsHex { + /// Use lower-case hexadecimal integers for the `Debug` trait (like [the `x?` type](../../std/fmt/index.html#formatting-traits)). + Lower, + /// Use upper-case hexadecimal integers for the `Debug` trait (like [the `X?` type](../../std/fmt/index.html#formatting-traits)). + Upper, +} + +/// Options for formatting. +/// +/// `FormattingOptions` is a [`Formatter`] without an attached [`Write`] trait. +/// It is mainly used to construct `Formatter` instances. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] +#[unstable(feature = "formatting_options", issue = "118117")] +pub struct FormattingOptions { + flags: u32, + fill: char, + align: Option, + width: Option, + precision: Option, +} + +impl FormattingOptions { + /// Construct a new `FormatterBuilder` with the supplied `Write` trait + /// object for output that is equivalent to the `{}` formatting + /// specifier: + /// + /// - no flags, + /// - filled with spaces, + /// - no alignment, + /// - no width, + /// - no precision, and + /// - no [`DebugAsHex`] output mode. + #[unstable(feature = "formatting_options", issue = "118117")] + pub const fn new() -> Self { + Self { flags: 0, fill: ' ', align: None, width: None, precision: None } + } + + /// Sets or removes the sign (the `+` or the `-` flag). + /// + /// - `+`: This is intended for numeric types and indicates that the sign + /// should always be printed. By default only the negative sign of signed + /// values is printed, and the sign of positive or unsigned values is + /// omitted. This flag indicates that the correct sign (+ or -) should + /// always be printed. + /// - `-`: Currently not used + #[unstable(feature = "formatting_options", issue = "118117")] + pub fn sign(&mut self, sign: Option) -> &mut Self { + self.flags = + self.flags & !(1 << rt::Flag::SignMinus as u32 | 1 << rt::Flag::SignPlus as u32); + match sign { + None => {} + Some(Sign::Plus) => self.flags |= 1 << rt::Flag::SignPlus as u32, + Some(Sign::Minus) => self.flags |= 1 << rt::Flag::SignMinus as u32, + } + self + } + /// Sets or unsets the `0` flag. + /// + /// This is used to indicate for integer formats that the padding to width should both be done with a 0 character as well as be sign-aware + #[unstable(feature = "formatting_options", issue = "118117")] + pub fn sign_aware_zero_pad(&mut self, sign_aware_zero_pad: bool) -> &mut Self { + if sign_aware_zero_pad { + self.flags |= 1 << rt::Flag::SignAwareZeroPad as u32 + } else { + self.flags &= !(1 << rt::Flag::SignAwareZeroPad as u32) + } + self + } + /// Sets or unsets the `#` flag. + /// + /// This flag indicates that the "alternate" form of printing should be + /// used. The alternate forms are: + /// - [`Debug`] : pretty-print the [`Debug`] formatting (adds linebreaks and indentation) + /// - [`LowerHex`] as well as [`UpperHex`] - precedes the argument with a `0x` + /// - [`Octal`] - precedes the argument with a `0b` + /// - [`Binary`] - precedes the argument with a `0o` + #[unstable(feature = "formatting_options", issue = "118117")] + pub fn alternate(&mut self, alternate: bool) -> &mut Self { + if alternate { + self.flags |= 1 << rt::Flag::Alternate as u32 + } else { + self.flags &= !(1 << rt::Flag::Alternate as u32) + } + self + } + /// Sets the fill character. + /// + /// The optional fill character and alignment is provided normally in + /// conjunction with the width parameter. This indicates that if the value + /// being formatted is smaller than width some extra characters will be + /// printed around it. + #[unstable(feature = "formatting_options", issue = "118117")] + pub fn fill(&mut self, fill: char) -> &mut Self { + self.fill = fill; + self + } + /// Sets or removes the alignment. + /// + /// The alignment specifies how the value being formatted should be + /// positioned if it is smaller than the width of the formatter. + #[unstable(feature = "formatting_options", issue = "118117")] + pub fn align(&mut self, align: Option) -> &mut Self { + self.align = align; + self + } + /// Sets or removes the width. + /// + /// This is a parameter for the “minimum width” that the format should take + /// up. If the value’s string does not fill up this many characters, then + /// the padding specified by [`FormattingOptions::fill`]/[`FormattingOptions::align`] + /// will be used to take up the required space. + #[unstable(feature = "formatting_options", issue = "118117")] + pub fn width(&mut self, width: Option) -> &mut Self { + self.width = width; + self + } + /// Sets or removes the precision. + /// + /// - For non-numeric types, this can be considered a “maximum width”. If + /// the resulting string is longer than this width, then it is truncated + /// down to this many characters and that truncated value is emitted with + /// proper fill, alignment and width if those parameters are set. + /// - For integral types, this is ignored. + /// - For floating-point types, this indicates how many digits after the + /// decimal point should be printed. + #[unstable(feature = "formatting_options", issue = "118117")] + pub fn precision(&mut self, precision: Option) -> &mut Self { + self.precision = precision; + self + } + /// Specifies whether the [`Debug`] trait should use lower-/upper-case + /// hexadecimal or normal integers + #[unstable(feature = "formatting_options", issue = "118117")] + pub fn debug_as_hex(&mut self, debug_as_hex: Option) -> &mut Self { + self.flags = self.flags + & !(1 << rt::Flag::DebugUpperHex as u32 | 1 << rt::Flag::DebugLowerHex as u32); + match debug_as_hex { + None => {} + Some(DebugAsHex::Upper) => self.flags |= 1 << rt::Flag::DebugUpperHex as u32, + Some(DebugAsHex::Lower) => self.flags |= 1 << rt::Flag::DebugLowerHex as u32, + } + self + } + + /// Returns the current sign (the `+` or the `-` flag). + #[unstable(feature = "formatting_options", issue = "118117")] + pub const fn get_sign(&self) -> Option { + const SIGN_PLUS_BITFIELD: u32 = 1 << rt::Flag::SignPlus as u32; + const SIGN_MINUS_BITFIELD: u32 = 1 << rt::Flag::SignMinus as u32; + match self.flags & ((1 << rt::Flag::SignPlus as u32) | (1 << rt::Flag::SignMinus as u32)) { + SIGN_PLUS_BITFIELD => Some(Sign::Plus), + SIGN_MINUS_BITFIELD => Some(Sign::Minus), + 0 => None, + _ => panic!("Invalid sign bits set in flags"), + } + } + /// Returns the current `0` flag. + #[unstable(feature = "formatting_options", issue = "118117")] + pub const fn get_sign_aware_zero_pad(&self) -> bool { + self.flags & (1 << rt::Flag::SignAwareZeroPad as u32) != 0 + } + /// Returns the current `#` flag. + #[unstable(feature = "formatting_options", issue = "118117")] + pub const fn get_alternate(&self) -> bool { + self.flags & (1 << rt::Flag::Alternate as u32) != 0 + } + /// Returns the current fill character. + #[unstable(feature = "formatting_options", issue = "118117")] + pub const fn get_fill(&self) -> char { + self.fill + } + /// Returns the current alignment. + #[unstable(feature = "formatting_options", issue = "118117")] + pub const fn get_align(&self) -> Option { + self.align + } + /// Returns the current width. + #[unstable(feature = "formatting_options", issue = "118117")] + pub const fn get_width(&self) -> Option { + self.width + } + /// Returns the current precision. + #[unstable(feature = "formatting_options", issue = "118117")] + pub const fn get_precision(&self) -> Option { + self.precision + } + /// Returns the current precision. + #[unstable(feature = "formatting_options", issue = "118117")] + pub const fn get_debug_as_hex(&self) -> Option { + const DEBUG_UPPER_BITFIELD: u32 = 1 << rt::Flag::DebugUpperHex as u32; + const DEBUG_LOWER_BITFIELD: u32 = 1 << rt::Flag::DebugLowerHex as u32; + match self.flags + & ((1 << rt::Flag::DebugUpperHex as u32) | (1 << rt::Flag::DebugLowerHex as u32)) + { + DEBUG_UPPER_BITFIELD => Some(DebugAsHex::Upper), + DEBUG_LOWER_BITFIELD => Some(DebugAsHex::Lower), + 0 => None, + _ => panic!("Invalid hex debug bits set in flags"), + } + } + + /// Creates a [`Formatter`] that writes its output to the given [`Write`] trait. + /// + /// You may alternatively use [`Formatter::new()`]. + #[unstable(feature = "formatting_options", issue = "118117")] + pub fn create_formatter<'a>(self, write: &'a mut (dyn Write + 'a)) -> Formatter<'a> { + Formatter { options: self, buf: write } + } + + #[doc(hidden)] + #[unstable( + feature = "fmt_internals", + reason = "internal routines only exposed for testing", + issue = "none" + )] + /// Flags for formatting + pub fn flags(&mut self, flags: u32) { + self.flags = flags + } + #[doc(hidden)] + #[unstable( + feature = "fmt_internals", + reason = "internal routines only exposed for testing", + issue = "none" + )] + /// Flags for formatting + pub fn get_flags(&self) -> u32 { + self.flags + } +} + /// Configuration for formatting. /// /// A `Formatter` represents various options related to formatting. Users do not @@ -260,34 +521,28 @@ impl Write for &mut W { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Formatter"] pub struct Formatter<'a> { - flags: u32, - fill: char, - align: rt::Alignment, - width: Option, - precision: Option, + options: FormattingOptions, buf: &'a mut (dyn Write + 'a), } impl<'a> Formatter<'a> { - /// Creates a new formatter with default settings. + /// Creates a new formatter with given [`FormattingOptions`]. /// - /// This can be used as a micro-optimization in cases where a full `Arguments` - /// structure (as created by `format_args!`) is not necessary; `Arguments` - /// is a little more expensive to use in simple formatting scenarios. + /// If `write` is a reference to a formatter, it is recommended to use + /// [`Formatter::with_options`] instead as this can borrow the underlying + /// `write`, thereby bypassing one layer of indirection. /// - /// Currently not intended for use outside of the standard library. - #[unstable(feature = "fmt_internals", reason = "internal to standard library", issue = "none")] - #[doc(hidden)] - pub fn new(buf: &'a mut (dyn Write + 'a)) -> Formatter<'a> { - Formatter { - flags: 0, - fill: ' ', - align: rt::Alignment::Unknown, - width: None, - precision: None, - buf, - } + /// You may alternatively use [`FormattingOptions::create_formatter()`]. + #[unstable(feature = "formatting_options", issue = "118117")] + pub fn new(write: &'a mut (dyn Write + 'a), options: FormattingOptions) -> Self { + Formatter { options, buf: write } + } + + /// Creates a new formatter based on this one with given [`FormattingOptions`]. + #[unstable(feature = "formatting_options", issue = "118117")] + pub fn with_options<'b>(&'b mut self, options: FormattingOptions) -> Formatter<'b> { + Formatter { options, buf: self.buf } } } @@ -333,10 +588,6 @@ pub struct Arguments<'a> { #[unstable(feature = "fmt_internals", issue = "none")] impl<'a> Arguments<'a> { #[inline] - #[cfg_attr( - bootstrap, - rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none") - )] pub const fn new_const(pieces: &'a [&'static str; N]) -> Self { const { assert!(N <= 1) }; Arguments { pieces, fmt: None, args: &[] } @@ -345,7 +596,7 @@ impl<'a> Arguments<'a> { /// When using the format_args!() macro, this function is used to generate the /// Arguments structure. #[inline] - pub fn new_v1( + pub const fn new_v1( pieces: &'a [&'static str; P], args: &'a [rt::Argument<'a>; A], ) -> Arguments<'a> { @@ -361,7 +612,7 @@ impl<'a> Arguments<'a> { /// 2. Every `rt::Placeholder::position` value within `fmt` must be a valid index of `args`. /// 3. Every `rt::Count::Param` within `fmt` must contain a valid index of `args`. #[inline] - pub fn new_v1_formatted( + pub const fn new_v1_formatted( pieces: &'a [&'static str], args: &'a [rt::Argument<'a>], fmt: &'a [rt::Placeholder], @@ -438,7 +689,7 @@ impl<'a> Arguments<'a> { /// assert_eq!(format_args!("{:?}", std::env::current_dir()).as_str(), None); /// ``` #[stable(feature = "fmt_as_str", since = "1.52.0")] - #[rustc_const_stable(feature = "const_arguments_as_str", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_arguments_as_str", since = "1.84.0")] #[must_use] #[inline] pub const fn as_str(&self) -> Option<&'static str> { @@ -1169,7 +1420,7 @@ pub trait UpperExp { /// [`write!`]: crate::write! #[stable(feature = "rust1", since = "1.0.0")] pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { - let mut formatter = Formatter::new(output); + let mut formatter = Formatter::new(output, FormattingOptions::new()); let mut idx = 0; match args.fmt { @@ -1218,14 +1469,14 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { } unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[rt::Argument<'_>]) -> Result { - fmt.fill = arg.fill; - fmt.align = arg.align; - fmt.flags = arg.flags; + fmt.options.fill = arg.fill; + fmt.options.align = arg.align.into(); + fmt.options.flags = arg.flags; // SAFETY: arg and args come from the same Arguments, // which guarantees the indexes are always within bounds. unsafe { - fmt.width = getcount(args, &arg.width); - fmt.precision = getcount(args, &arg.precision); + fmt.options.width = getcount(args, &arg.width); + fmt.options.precision = getcount(args, &arg.precision); } // Extract the correct argument @@ -1284,11 +1535,7 @@ impl<'a> Formatter<'a> { buf: wrap(self.buf), // And preserve these - flags: self.flags, - fill: self.fill, - align: self.align, - width: self.width, - precision: self.precision, + options: self.options, } } @@ -1369,7 +1616,7 @@ impl<'a> Formatter<'a> { } // The `width` field is more of a `min-width` parameter at this point. - match self.width { + match self.options.width { // If there's no minimum length requirements then we can just // write the bytes. None => { @@ -1385,14 +1632,15 @@ impl<'a> Formatter<'a> { // The sign and prefix goes before the padding if the fill character // is zero Some(min) if self.sign_aware_zero_pad() => { - let old_fill = crate::mem::replace(&mut self.fill, '0'); - let old_align = crate::mem::replace(&mut self.align, rt::Alignment::Right); + let old_fill = crate::mem::replace(&mut self.options.fill, '0'); + let old_align = + crate::mem::replace(&mut self.options.align, Some(Alignment::Right)); write_prefix(self, sign, prefix)?; let post_padding = self.padding(min - width, Alignment::Right)?; self.buf.write_str(buf)?; post_padding.write(self)?; - self.fill = old_fill; - self.align = old_align; + self.options.fill = old_fill; + self.options.align = old_align; Ok(()) } // Otherwise, the sign and prefix goes after the padding @@ -1437,12 +1685,12 @@ impl<'a> Formatter<'a> { #[stable(feature = "rust1", since = "1.0.0")] pub fn pad(&mut self, s: &str) -> Result { // Make sure there's a fast path up front - if self.width.is_none() && self.precision.is_none() { + if self.options.width.is_none() && self.options.precision.is_none() { return self.buf.write_str(s); } // The `precision` field can be interpreted as a `max-width` for the // string being formatted. - let s = if let Some(max) = self.precision { + let s = if let Some(max) = self.options.precision { // If our string is longer that the precision, then we must have // truncation. However other flags like `fill`, `width` and `align` // must act as always. @@ -1459,7 +1707,7 @@ impl<'a> Formatter<'a> { &s }; // The `width` field is more of a `min-width` parameter at this point. - match self.width { + match self.options.width { // If we're under the maximum length, and there's no minimum length // requirements, then we can just emit the string None => self.buf.write_str(s), @@ -1491,12 +1739,7 @@ impl<'a> Formatter<'a> { padding: usize, default: Alignment, ) -> result::Result { - let align = match self.align { - rt::Alignment::Unknown => default, - rt::Alignment::Left => Alignment::Left, - rt::Alignment::Right => Alignment::Right, - rt::Alignment::Center => Alignment::Center, - }; + let align = self.align().unwrap_or(default); let (pre_pad, post_pad) = match align { Alignment::Left => (0, padding), @@ -1505,10 +1748,10 @@ impl<'a> Formatter<'a> { }; for _ in 0..pre_pad { - self.buf.write_char(self.fill)?; + self.buf.write_char(self.options.fill)?; } - Ok(PostPadding::new(self.fill, post_pad)) + Ok(PostPadding::new(self.options.fill, post_pad)) } /// Takes the formatted parts and applies the padding. @@ -1520,12 +1763,12 @@ impl<'a> Formatter<'a> { /// /// Any `numfmt::Part::Copy` parts in `formatted` must contain valid UTF-8. unsafe fn pad_formatted_parts(&mut self, formatted: &numfmt::Formatted<'_>) -> Result { - if let Some(mut width) = self.width { + if let Some(mut width) = self.options.width { // for the sign-aware zero padding, we render the sign first and // behave as if we had no sign from the beginning. let mut formatted = formatted.clone(); - let old_fill = self.fill; - let old_align = self.align; + let old_fill = self.options.fill; + let old_align = self.options.align; if self.sign_aware_zero_pad() { // a sign always goes first let sign = formatted.sign; @@ -1534,8 +1777,8 @@ impl<'a> Formatter<'a> { // remove the sign from the formatted parts formatted.sign = ""; width = width.saturating_sub(sign.len()); - self.fill = '0'; - self.align = rt::Alignment::Right; + self.options.fill = '0'; + self.options.align = Some(Alignment::Right); } // remaining parts go through the ordinary padding process. @@ -1552,8 +1795,8 @@ impl<'a> Formatter<'a> { } post_padding.write(self) }; - self.fill = old_fill; - self.align = old_align; + self.options.fill = old_fill; + self.options.align = old_align; ret } else { // this is the common case and we take a shortcut @@ -1679,7 +1922,7 @@ impl<'a> Formatter<'a> { or `sign_aware_zero_pad` methods instead" )] pub fn flags(&self) -> u32 { - self.flags + self.options.flags } /// Returns the character used as 'fill' whenever there is alignment. @@ -1712,7 +1955,7 @@ impl<'a> Formatter<'a> { #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn fill(&self) -> char { - self.fill + self.options.fill } /// Returns a flag indicating what form of alignment was requested. @@ -1747,12 +1990,7 @@ impl<'a> Formatter<'a> { #[must_use] #[stable(feature = "fmt_flags_align", since = "1.28.0")] pub fn align(&self) -> Option { - match self.align { - rt::Alignment::Left => Some(Alignment::Left), - rt::Alignment::Right => Some(Alignment::Right), - rt::Alignment::Center => Some(Alignment::Center), - rt::Alignment::Unknown => None, - } + self.options.align } /// Returns the optionally specified integer width that the output should be. @@ -1782,7 +2020,7 @@ impl<'a> Formatter<'a> { #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn width(&self) -> Option { - self.width + self.options.width } /// Returns the optionally specified precision for numeric types. @@ -1813,7 +2051,7 @@ impl<'a> Formatter<'a> { #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn precision(&self) -> Option { - self.precision + self.options.precision } /// Determines if the `+` flag was specified. @@ -1845,7 +2083,7 @@ impl<'a> Formatter<'a> { #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn sign_plus(&self) -> bool { - self.flags & (1 << rt::Flag::SignPlus as u32) != 0 + self.options.flags & (1 << rt::Flag::SignPlus as u32) != 0 } /// Determines if the `-` flag was specified. @@ -1874,7 +2112,7 @@ impl<'a> Formatter<'a> { #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn sign_minus(&self) -> bool { - self.flags & (1 << rt::Flag::SignMinus as u32) != 0 + self.options.flags & (1 << rt::Flag::SignMinus as u32) != 0 } /// Determines if the `#` flag was specified. @@ -1902,7 +2140,7 @@ impl<'a> Formatter<'a> { #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn alternate(&self) -> bool { - self.flags & (1 << rt::Flag::Alternate as u32) != 0 + self.options.flags & (1 << rt::Flag::Alternate as u32) != 0 } /// Determines if the `0` flag was specified. @@ -1928,17 +2166,17 @@ impl<'a> Formatter<'a> { #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn sign_aware_zero_pad(&self) -> bool { - self.flags & (1 << rt::Flag::SignAwareZeroPad as u32) != 0 + self.options.flags & (1 << rt::Flag::SignAwareZeroPad as u32) != 0 } // FIXME: Decide what public API we want for these two flags. // https://github.com/rust-lang/rust/issues/48584 fn debug_lower_hex(&self) -> bool { - self.flags & (1 << rt::Flag::DebugLowerHex as u32) != 0 + self.options.flags & (1 << rt::Flag::DebugLowerHex as u32) != 0 } fn debug_upper_hex(&self) -> bool { - self.flags & (1 << rt::Flag::DebugUpperHex as u32) != 0 + self.options.flags & (1 << rt::Flag::DebugUpperHex as u32) != 0 } /// Creates a [`DebugStruct`] builder designed to assist with creation of @@ -2354,6 +2592,18 @@ impl<'a> Formatter<'a> { pub fn debug_map<'b>(&'b mut self) -> DebugMap<'b, 'a> { builders::debug_map_new(self) } + + /// Returns the sign of this formatter (`+` or `-`). + #[unstable(feature = "formatting_options", issue = "118117")] + pub const fn sign(&self) -> Option { + self.options.get_sign() + } + + /// Returns the formatting options this formatter corresponds to. + #[unstable(feature = "formatting_options", issue = "118117")] + pub const fn options(&self) -> FormattingOptions { + self.options + } } #[stable(since = "1.2.0", feature = "formatter_write")] @@ -2506,7 +2756,7 @@ impl Debug for char { #[stable(feature = "rust1", since = "1.0.0")] impl Display for char { fn fmt(&self, f: &mut Formatter<'_>) -> Result { - if f.width.is_none() && f.precision.is_none() { + if f.options.width.is_none() && f.options.precision.is_none() { f.write_char(*self) } else { f.pad(self.encode_utf8(&mut [0; 4])) @@ -2530,26 +2780,26 @@ impl Pointer for *const T { /// /// [problematic]: https://github.com/rust-lang/rust/issues/95489 pub(crate) fn pointer_fmt_inner(ptr_addr: usize, f: &mut Formatter<'_>) -> Result { - let old_width = f.width; - let old_flags = f.flags; + let old_width = f.options.width; + let old_flags = f.options.flags; // The alternate flag is already treated by LowerHex as being special- // it denotes whether to prefix with 0x. We use it to work out whether // or not to zero extend, and then unconditionally set it to get the // prefix. if f.alternate() { - f.flags |= 1 << (rt::Flag::SignAwareZeroPad as u32); + f.options.flags |= 1 << (rt::Flag::SignAwareZeroPad as u32); - if f.width.is_none() { - f.width = Some((usize::BITS / 4) as usize + 2); + if f.options.width.is_none() { + f.options.width = Some((usize::BITS / 4) as usize + 2); } } - f.flags |= 1 << (rt::Flag::Alternate as u32); + f.options.flags |= 1 << (rt::Flag::Alternate as u32); let ret = LowerHex::fmt(&ptr_addr, f); - f.width = old_width; - f.flags = old_flags; + f.options.width = old_width; + f.options.flags = old_flags; ret } diff --git a/core/src/fmt/rt.rs b/core/src/fmt/rt.rs index af6f0da88de67..85d089a079082 100644 --- a/core/src/fmt/rt.rs +++ b/core/src/fmt/rt.rs @@ -19,7 +19,7 @@ pub struct Placeholder { } impl Placeholder { - #[inline(always)] + #[inline] pub const fn new( position: usize, fill: char, @@ -95,13 +95,13 @@ pub struct Argument<'a> { #[rustc_diagnostic_item = "ArgumentMethods"] impl Argument<'_> { - #[inline(always)] - fn new<'a, T>(x: &'a T, f: fn(&T, &mut Formatter<'_>) -> Result) -> Argument<'a> { + #[inline] + const fn new<'a, T>(x: &'a T, f: fn(&T, &mut Formatter<'_>) -> Result) -> Argument<'a> { Argument { // INVARIANT: this creates an `ArgumentType<'a>` from a `&'a T` and // a `fn(&T, ...)`, so the invariant is maintained. ty: ArgumentType::Placeholder { - value: NonNull::from(x).cast(), + value: NonNull::from_ref(x).cast(), // SAFETY: function pointers always have the same layout. formatter: unsafe { mem::transmute(f) }, _lifetime: PhantomData, @@ -109,48 +109,48 @@ impl Argument<'_> { } } - #[inline(always)] + #[inline] pub fn new_display(x: &T) -> Argument<'_> { Self::new(x, Display::fmt) } - #[inline(always)] + #[inline] pub fn new_debug(x: &T) -> Argument<'_> { Self::new(x, Debug::fmt) } - #[inline(always)] + #[inline] pub fn new_debug_noop(x: &T) -> Argument<'_> { Self::new(x, |_, _| Ok(())) } - #[inline(always)] + #[inline] pub fn new_octal(x: &T) -> Argument<'_> { Self::new(x, Octal::fmt) } - #[inline(always)] + #[inline] pub fn new_lower_hex(x: &T) -> Argument<'_> { Self::new(x, LowerHex::fmt) } - #[inline(always)] + #[inline] pub fn new_upper_hex(x: &T) -> Argument<'_> { Self::new(x, UpperHex::fmt) } - #[inline(always)] + #[inline] pub fn new_pointer(x: &T) -> Argument<'_> { Self::new(x, Pointer::fmt) } - #[inline(always)] + #[inline] pub fn new_binary(x: &T) -> Argument<'_> { Self::new(x, Binary::fmt) } - #[inline(always)] + #[inline] pub fn new_lower_exp(x: &T) -> Argument<'_> { Self::new(x, LowerExp::fmt) } - #[inline(always)] + #[inline] pub fn new_upper_exp(x: &T) -> Argument<'_> { Self::new(x, UpperExp::fmt) } - #[inline(always)] - pub fn from_usize(x: &usize) -> Argument<'_> { + #[inline] + pub const fn from_usize(x: &usize) -> Argument<'_> { Argument { ty: ArgumentType::Count(*x) } } @@ -164,7 +164,7 @@ impl Argument<'_> { // it here is an explicit CFI violation. #[allow(inline_no_sanitize)] #[no_sanitize(cfi, kcfi)] - #[inline(always)] + #[inline] pub(super) unsafe fn fmt(&self, f: &mut Formatter<'_>) -> Result { match self.ty { // SAFETY: @@ -180,8 +180,8 @@ impl Argument<'_> { } } - #[inline(always)] - pub(super) fn as_usize(&self) -> Option { + #[inline] + pub(super) const fn as_usize(&self) -> Option { match self.ty { ArgumentType::Count(count) => Some(count), ArgumentType::Placeholder { .. } => None, @@ -198,8 +198,8 @@ impl Argument<'_> { /// let f = format_args!("{}", "a"); /// println!("{f}"); /// ``` - #[inline(always)] - pub fn none() -> [Self; 0] { + #[inline] + pub const fn none() -> [Self; 0] { [] } } @@ -215,8 +215,8 @@ pub struct UnsafeArg { impl UnsafeArg { /// See documentation where `UnsafeArg` is required to know when it is safe to /// create and use `UnsafeArg`. - #[inline(always)] - pub unsafe fn new() -> Self { + #[inline] + pub const unsafe fn new() -> Self { Self { _private: () } } } diff --git a/core/src/future/async_drop.rs b/core/src/future/async_drop.rs index 7de5fe67cd096..f1778a4d782af 100644 --- a/core/src/future/async_drop.rs +++ b/core/src/future/async_drop.rs @@ -133,7 +133,8 @@ pub trait AsyncDrop { } #[lang = "async_destruct"] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[rustc_deny_explicit_impl] +#[rustc_do_not_implement_via_object] trait AsyncDestruct { type AsyncDestructor: Future; } diff --git a/core/src/future/future.rs b/core/src/future/future.rs index 234914c20fc31..cfbd88bbe7998 100644 --- a/core/src/future/future.rs +++ b/core/src/future/future.rs @@ -25,7 +25,7 @@ use crate::task::{Context, Poll}; /// [`async`]: ../../std/keyword.async.html /// [`Waker`]: crate::task::Waker #[doc(notable_trait)] -#[cfg_attr(not(bootstrap), doc(search_unbox))] +#[doc(search_unbox)] #[must_use = "futures do nothing unless you `.await` or poll them"] #[stable(feature = "futures_api", since = "1.36.0")] #[lang = "future_trait"] diff --git a/core/src/hash/mod.rs b/core/src/hash/mod.rs index 061690e88ddf8..7a6630c82d0da 100644 --- a/core/src/hash/mod.rs +++ b/core/src/hash/mod.rs @@ -752,11 +752,8 @@ pub struct BuildHasherDefault(marker::PhantomData H>); impl BuildHasherDefault { /// Creates a new BuildHasherDefault for Hasher `H`. - #[unstable( - feature = "build_hasher_default_const_new", - issue = "123197", - reason = "recently added" - )] + #[stable(feature = "build_hasher_default_const_new", since = "1.85.0")] + #[rustc_const_stable(feature = "build_hasher_default_const_new", since = "1.85.0")] pub const fn new() -> Self { BuildHasherDefault(marker::PhantomData) } diff --git a/core/src/hint.rs b/core/src/hint.rs index 78df51f2bc47d..9c054b99a27ac 100644 --- a/core/src/hint.rs +++ b/core/src/hint.rs @@ -310,6 +310,8 @@ pub fn spin_loop() { /// behavior in the calling code. This property makes `black_box` useful for writing code in which /// certain optimizations are not desired, such as benchmarks. /// +///
+/// /// Note however, that `black_box` is only (and can only be) provided on a "best-effort" basis. The /// extent to which it can block optimisations may vary depending upon the platform and code-gen /// backend used. Programs cannot rely on `black_box` for *correctness*, beyond it behaving as the @@ -317,6 +319,8 @@ pub fn spin_loop() { /// This also means that this function does not offer any guarantees for cryptographic or security /// purposes. /// +///
+/// /// [`std::convert::identity`]: crate::convert::identity /// /// # When is this useful? @@ -357,7 +361,7 @@ pub fn spin_loop() { /// ``` /// use std::hint::black_box; /// -/// // Same `contains` function +/// // Same `contains` function. /// fn contains(haystack: &[&str], needle: &str) -> bool { /// haystack.iter().any(|x| x == &needle) /// } @@ -366,8 +370,13 @@ pub fn spin_loop() { /// let haystack = vec!["abc", "def", "ghi", "jkl", "mno"]; /// let needle = "ghi"; /// for _ in 0..10 { -/// // Adjust our benchmark loop contents -/// black_box(contains(black_box(&haystack), black_box(needle))); +/// // Force the compiler to run `contains`, even though it is a pure function whose +/// // results are unused. +/// black_box(contains( +/// // Prevent the compiler from making assumptions about the input. +/// black_box(&haystack), +/// black_box(needle), +/// )); /// } /// } /// ``` @@ -382,6 +391,83 @@ pub fn spin_loop() { /// /// This makes our benchmark much more realistic to how the function would actually be used, where /// arguments are usually not known at compile time and the result is used in some way. +/// +/// # How to use this +/// +/// In practice, `black_box` serves two purposes: +/// +/// 1. It prevents the compiler from making optimizations related to the value returned by `black_box` +/// 2. It forces the value passed to `black_box` to be calculated, even if the return value of `black_box` is unused +/// +/// ``` +/// use std::hint::black_box; +/// +/// let zero = 0; +/// let five = 5; +/// +/// // The compiler will see this and remove the `* five` call, because it knows that multiplying +/// // any integer by 0 will result in 0. +/// let c = zero * five; +/// +/// // Adding `black_box` here disables the compiler's ability to reason about the first operand in the multiplication. +/// // It is forced to assume that it can be any possible number, so it cannot remove the `* five` +/// // operation. +/// let c = black_box(zero) * five; +/// ``` +/// +/// While most cases will not be as clear-cut as the above example, it still illustrates how +/// `black_box` can be used. When benchmarking a function, you usually want to wrap its inputs in +/// `black_box` so the compiler cannot make optimizations that would be unrealistic in real-life +/// use. +/// +/// ``` +/// use std::hint::black_box; +/// +/// // This is a simple function that increments its input by 1. Note that it is pure, meaning it +/// // has no side-effects. This function has no effect if its result is unused. (An example of a +/// // function *with* side-effects is `println!()`.) +/// fn increment(x: u8) -> u8 { +/// x + 1 +/// } +/// +/// // Here, we call `increment` but discard its result. The compiler, seeing this and knowing that +/// // `increment` is pure, will eliminate this function call entirely. This may not be desired, +/// // though, especially if we're trying to track how much time `increment` takes to execute. +/// let _ = increment(black_box(5)); +/// +/// // Here, we force `increment` to be executed. This is because the compiler treats `black_box` +/// // as if it has side-effects, and thus must compute its input. +/// let _ = black_box(increment(black_box(5))); +/// ``` +/// +/// There may be additional situations where you want to wrap the result of a function in +/// `black_box` to force its execution. This is situational though, and may not have any effect +/// (such as when the function returns a zero-sized type such as [`()` unit][unit]). +/// +/// Note that `black_box` has no effect on how its input is treated, only its output. As such, +/// expressions passed to `black_box` may still be optimized: +/// +/// ``` +/// use std::hint::black_box; +/// +/// // The compiler sees this... +/// let y = black_box(5 * 10); +/// +/// // ...as this. As such, it will likely simplify `5 * 10` to just `50`. +/// let _0 = 5 * 10; +/// let y = black_box(_0); +/// ``` +/// +/// In the above example, the `5 * 10` expression is considered distinct from the `black_box` call, +/// and thus is still optimized by the compiler. You can prevent this by moving the multiplication +/// operation outside of `black_box`: +/// +/// ``` +/// use std::hint::black_box; +/// +/// // No assumptions can be made about either operand, so the multiplication is not optimized out. +/// let y = black_box(5) * black_box(10); +/// ``` #[inline] #[stable(feature = "bench_black_box", since = "1.66.0")] #[rustc_const_unstable(feature = "const_black_box", issue = "none")] @@ -506,7 +592,6 @@ pub const fn black_box(dummy: T) -> T { /// # } /// ``` #[unstable(feature = "hint_must_use", issue = "94745")] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "hint_must_use", issue = "94745"))] #[must_use] // <-- :) #[inline(always)] pub const fn must_use(value: T) -> T { diff --git a/core/src/intrinsics/fallback.rs b/core/src/intrinsics/fallback.rs new file mode 100644 index 0000000000000..70484e4d0f2a1 --- /dev/null +++ b/core/src/intrinsics/fallback.rs @@ -0,0 +1,112 @@ +#![unstable( + feature = "core_intrinsics_fallbacks", + reason = "The fallbacks will never be stable, as they exist only to be called \ + by the fallback MIR, but they're exported so they can be tested on \ + platforms where the fallback MIR isn't actually used", + issue = "none" +)] +#![allow(missing_docs)] + +#[const_trait] +#[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")] +pub trait CarryingMulAdd: Copy + 'static { + type Unsigned: Copy + 'static; + fn carrying_mul_add( + self, + multiplicand: Self, + addend: Self, + carry: Self, + ) -> (Self::Unsigned, Self); +} + +macro_rules! impl_carrying_mul_add_by_widening { + ($($t:ident $u:ident $w:ident,)+) => {$( + #[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")] + impl const CarryingMulAdd for $t { + type Unsigned = $u; + #[inline] + fn carrying_mul_add(self, a: Self, b: Self, c: Self) -> ($u, $t) { + let wide = (self as $w) * (a as $w) + (b as $w) + (c as $w); + (wide as _, (wide >> Self::BITS) as _) + } + } + )+}; +} +impl_carrying_mul_add_by_widening! { + u8 u8 u16, + u16 u16 u32, + u32 u32 u64, + u64 u64 u128, + usize usize UDoubleSize, + i8 u8 i16, + i16 u16 i32, + i32 u32 i64, + i64 u64 i128, + isize usize UDoubleSize, +} + +#[cfg(target_pointer_width = "16")] +type UDoubleSize = u32; +#[cfg(target_pointer_width = "32")] +type UDoubleSize = u64; +#[cfg(target_pointer_width = "64")] +type UDoubleSize = u128; + +#[inline] +const fn wide_mul_u128(a: u128, b: u128) -> (u128, u128) { + #[inline] + const fn to_low_high(x: u128) -> [u128; 2] { + const MASK: u128 = u64::MAX as _; + [x & MASK, x >> 64] + } + #[inline] + const fn from_low_high(x: [u128; 2]) -> u128 { + x[0] | (x[1] << 64) + } + #[inline] + const fn scalar_mul(low_high: [u128; 2], k: u128) -> [u128; 3] { + let [x, c] = to_low_high(k * low_high[0]); + let [y, z] = to_low_high(k * low_high[1] + c); + [x, y, z] + } + let a = to_low_high(a); + let b = to_low_high(b); + let low = scalar_mul(a, b[0]); + let high = scalar_mul(a, b[1]); + let r0 = low[0]; + let [r1, c] = to_low_high(low[1] + high[0]); + let [r2, c] = to_low_high(low[2] + high[1] + c); + let r3 = high[2] + c; + (from_low_high([r0, r1]), from_low_high([r2, r3])) +} + +#[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")] +impl const CarryingMulAdd for u128 { + type Unsigned = u128; + #[inline] + fn carrying_mul_add(self, b: u128, c: u128, d: u128) -> (u128, u128) { + let (low, mut high) = wide_mul_u128(self, b); + let (low, carry) = u128::overflowing_add(low, c); + high += carry as u128; + let (low, carry) = u128::overflowing_add(low, d); + high += carry as u128; + (low, high) + } +} + +#[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")] +impl const CarryingMulAdd for i128 { + type Unsigned = u128; + #[inline] + fn carrying_mul_add(self, b: i128, c: i128, d: i128) -> (u128, i128) { + let (low, high) = wide_mul_u128(self as u128, b as u128); + let mut high = high as i128; + high = high.wrapping_add(i128::wrapping_mul(self >> 127, b)); + high = high.wrapping_add(i128::wrapping_mul(self, b >> 127)); + let (low, carry) = u128::overflowing_add(low, c as u128); + high = high.wrapping_add((carry as i128) + (c >> 127)); + let (low, carry) = u128::overflowing_add(low, d as u128); + high = high.wrapping_add((carry as i128) + (d >> 127)); + (low, high) + } +} diff --git a/core/src/intrinsics/mir.rs b/core/src/intrinsics/mir.rs index 6539964bc0956..834f44c7790d9 100644 --- a/core/src/intrinsics/mir.rs +++ b/core/src/intrinsics/mir.rs @@ -233,7 +233,7 @@ //! //! - Operands implicitly convert to `Use` rvalues. //! - `&`, `&mut`, `addr_of!`, and `addr_of_mut!` all work to create their associated rvalue. -//! - [`Discriminant`], [`Len`], and [`CopyForDeref`] have associated functions. +//! - [`Discriminant`] and [`CopyForDeref`] have associated functions. //! - Unary and binary operations use their normal Rust syntax - `a * b`, `!c`, etc. //! - The binary operation `Offset` can be created via [`Offset`]. //! - Checked binary operations are represented by wrapping the associated binop in [`Checked`]. @@ -249,6 +249,39 @@ //! `Call(ret_val = function(arg1, arg2, ...), ReturnTo(next_block), UnwindContinue())`. //! - [`TailCall`] does not have a return destination or next block, so its syntax is just //! `TailCall(function(arg1, arg2, ...))`. +//! +//! #### Debuginfo +//! +//! Debuginfo associates source code variable names (of variables that may not exist any more) with +//! MIR expressions that indicate where the value of that variable is stored. The syntax to do so +//! is: +//! ```text +//! debug source_var_name => expression; +//! ``` +//! Both places and constants are supported in the `expression`. +//! +//! ```rust +//! #![allow(internal_features)] +//! #![feature(core_intrinsics, custom_mir)] +//! +//! use core::intrinsics::mir::*; +//! +//! #[custom_mir(dialect = "built")] +//! fn debuginfo(arg: Option<&i32>) { +//! mir!( +//! // Debuginfo for a source variable `plain_local` that just duplicates `arg`. +//! debug plain_local => arg; +//! // Debuginfo for a source variable `projection` that can be computed by dereferencing +//! // a field of `arg`. +//! debug projection => *Field::<&i32>(Variant(arg, 1), 0); +//! // Debuginfo for a source variable `constant` that always holds the value `5`. +//! debug constant => 5_usize; +//! { +//! Return() +//! } +//! ) +//! } +//! ``` #![unstable( feature = "custom_mir", @@ -368,7 +401,6 @@ define!("mir_storage_dead", fn StorageDead(local: T)); define!("mir_assume", fn Assume(operand: bool)); define!("mir_deinit", fn Deinit(place: T)); define!("mir_checked", fn Checked(binop: T) -> (T, bool)); -define!("mir_len", fn Len(place: T) -> usize); define!( "mir_ptr_metadata", fn PtrMetadata(place: *const P) ->

::Metadata diff --git a/core/src/intrinsics/mod.rs b/core/src/intrinsics/mod.rs index 2f75bfae988f2..41b2ffad6680d 100644 --- a/core/src/intrinsics/mod.rs +++ b/core/src/intrinsics/mod.rs @@ -68,6 +68,7 @@ use crate::marker::{DiscriminantKind, Tuple}; use crate::mem::SizedTypeProperties; use crate::{ptr, ub_checks}; +pub mod fallback; pub mod mir; pub mod simd; @@ -1381,7 +1382,7 @@ pub unsafe fn prefetch_write_instruction(_data: *const T, _locality: i32) { #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn breakpoint() { +pub fn breakpoint() { unreachable!() } @@ -1431,11 +1432,7 @@ pub fn abort() -> ! { /// reach code marked with this function. /// /// The stabilized version of this intrinsic is [`core::hint::unreachable_unchecked`]. -#[cfg_attr( - bootstrap, - rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0") -)] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -1453,8 +1450,7 @@ pub const unsafe fn unreachable() -> ! { /// own, or if it does not enable any significant optimizations. /// /// The stabilized version of this intrinsic is [`core::hint::assert_unchecked`]. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assume", since = "1.77.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] @@ -1474,8 +1470,7 @@ pub const unsafe fn assume(b: bool) { /// /// This intrinsic does not have a stable counterpart. #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(not(bootstrap), rustc_intrinsic)] -#[cfg(not(bootstrap))] +#[rustc_intrinsic] #[rustc_nounwind] #[miri::intrinsic_fallback_is_spec] #[cold] @@ -1492,19 +1487,10 @@ pub const fn cold_path() {} /// any safety invariants. /// /// This intrinsic does not have a stable counterpart. -#[cfg_attr( - bootstrap, - rustc_const_stable(feature = "const_likely", since = "CURRENT_RUSTC_VERSION") -)] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_nounwind] #[inline(always)] pub const fn likely(b: bool) -> bool { - #[cfg(bootstrap)] - { - b - } - #[cfg(not(bootstrap))] if b { true } else { @@ -1524,19 +1510,10 @@ pub const fn likely(b: bool) -> bool { /// any safety invariants. /// /// This intrinsic does not have a stable counterpart. -#[cfg_attr( - bootstrap, - rustc_const_stable(feature = "const_likely", since = "CURRENT_RUSTC_VERSION") -)] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_nounwind] #[inline(always)] pub const fn unlikely(b: bool) -> bool { - #[cfg(bootstrap)] - { - b - } - #[cfg(not(bootstrap))] if b { cold_path(); true @@ -1556,7 +1533,7 @@ pub const fn unlikely(b: bool) -> bool { /// Therefore, implementations must not require the user to uphold /// any safety invariants. /// -/// This intrinsic does not have a stable counterpart. +/// The public form of this instrinsic is [`bool::select_unpredictable`]. #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] #[rustc_nounwind] @@ -1570,8 +1547,7 @@ pub fn select_unpredictable(b: bool, true_val: T, false_val: T) -> T { /// This will statically either panic, or do nothing. /// /// This intrinsic does not have a stable counterpart. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assert_type", since = "1.59.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -1583,8 +1559,7 @@ pub const fn assert_inhabited() { /// zero-initialization: This will statically either panic, or do nothing. /// /// This intrinsic does not have a stable counterpart. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assert_type2", since = "1.75.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -1595,8 +1570,7 @@ pub const fn assert_zero_valid() { /// A guard for `std::mem::uninitialized`. This will statically either panic, or do nothing. /// /// This intrinsic does not have a stable counterpart. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assert_type2", since = "1.75.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -1612,8 +1586,7 @@ pub const fn assert_mem_uninitialized_valid() { /// any safety invariants. /// /// Consider using [`core::panic::Location::caller`] instead. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_caller_location", since = "1.79.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -1630,8 +1603,7 @@ pub const fn caller_location() -> &'static crate::panic::Location<'static> { /// it does not require an `unsafe` block. /// Therefore, implementations must not require the user to uphold /// any safety invariants. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_intrinsic_forget", since = "1.83.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -1925,744 +1897,1098 @@ pub const fn forget(_: T) { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_allowed_through_unstable_modules] +#[cfg_attr(bootstrap, rustc_allowed_through_unstable_modules)] +#[cfg_attr( + not(bootstrap), + rustc_allowed_through_unstable_modules = "import this function via `std::mem` instead" +)] #[rustc_const_stable(feature = "const_transmute", since = "1.56.0")] #[rustc_diagnostic_item = "transmute"] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] -pub const unsafe fn transmute(_src: Src) -> Dst { +pub const unsafe fn transmute(_src: Src) -> Dst { + unreachable!() +} + +/// Like [`transmute`], but even less checked at compile-time: rather than +/// giving an error for `size_of::() != size_of::()`, it's +/// **Undefined Behavior** at runtime. +/// +/// Prefer normal `transmute` where possible, for the extra checking, since +/// both do exactly the same thing at runtime, if they both compile. +/// +/// This is not expected to ever be exposed directly to users, rather it +/// may eventually be exposed through some more-constrained API. +#[rustc_intrinsic_const_stable_indirect] +#[rustc_nounwind] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const unsafe fn transmute_unchecked(_src: Src) -> Dst { + unreachable!() +} + +/// Returns `true` if the actual type given as `T` requires drop +/// glue; returns `false` if the actual type provided for `T` +/// implements `Copy`. +/// +/// If the actual type neither requires drop glue nor implements +/// `Copy`, then the return value of this function is unspecified. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop). +#[rustc_intrinsic_const_stable_indirect] +#[rustc_nounwind] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const fn needs_drop() -> bool { + unreachable!() +} + +/// Calculates the offset from a pointer. +/// +/// This is implemented as an intrinsic to avoid converting to and from an +/// integer, since the conversion would throw away aliasing information. +/// +/// This can only be used with `Ptr` as a raw pointer type (`*mut` or `*const`) +/// to a `Sized` pointee and with `Delta` as `usize` or `isize`. Any other +/// instantiations may arbitrarily misbehave, and that's *not* a compiler bug. +/// +/// # Safety +/// +/// If the computed offset is non-zero, then both the starting and resulting pointer must be +/// either in bounds or at the end of an allocated object. If either pointer is out +/// of bounds or arithmetic overflow occurs then this operation is undefined behavior. +/// +/// The stabilized version of this intrinsic is [`pointer::offset`]. +#[must_use = "returns a new pointer rather than modifying its argument"] +#[rustc_intrinsic_const_stable_indirect] +#[rustc_nounwind] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const unsafe fn offset(_dst: Ptr, _offset: Delta) -> Ptr { + unreachable!() +} + +/// Calculates the offset from a pointer, potentially wrapping. +/// +/// This is implemented as an intrinsic to avoid converting to and from an +/// integer, since the conversion inhibits certain optimizations. +/// +/// # Safety +/// +/// Unlike the `offset` intrinsic, this intrinsic does not restrict the +/// resulting pointer to point into or at the end of an allocated +/// object, and it wraps with two's complement arithmetic. The resulting +/// value is not necessarily valid to be used to actually access memory. +/// +/// The stabilized version of this intrinsic is [`pointer::wrapping_offset`]. +#[must_use = "returns a new pointer rather than modifying its argument"] +#[rustc_intrinsic_const_stable_indirect] +#[rustc_nounwind] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const unsafe fn arith_offset(_dst: *const T, _offset: isize) -> *const T { + unreachable!() +} + +/// Masks out bits of the pointer according to a mask. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// Consider using [`pointer::mask`] instead. +#[rustc_nounwind] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub fn ptr_mask(_ptr: *const T, _mask: usize) -> *const T { + unreachable!() +} + +/// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with +/// a size of `count` * `size_of::()` and an alignment of +/// `min_align_of::()` +/// +/// The volatile parameter is set to `true`, so it will not be optimized out +/// unless size is equal to zero. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn volatile_copy_nonoverlapping_memory(_dst: *mut T, _src: *const T, _count: usize) { + unreachable!() +} +/// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with +/// a size of `count * size_of::()` and an alignment of +/// `min_align_of::()` +/// +/// The volatile parameter is set to `true`, so it will not be optimized out +/// unless size is equal to zero. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn volatile_copy_memory(_dst: *mut T, _src: *const T, _count: usize) { + unreachable!() +} +/// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a +/// size of `count * size_of::()` and an alignment of +/// `min_align_of::()`. +/// +/// The volatile parameter is set to `true`, so it will not be optimized out +/// unless size is equal to zero. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn volatile_set_memory(_dst: *mut T, _val: u8, _count: usize) { + unreachable!() +} + +/// Performs a volatile load from the `src` pointer. +/// +/// The stabilized version of this intrinsic is [`core::ptr::read_volatile`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn volatile_load(_src: *const T) -> T { + unreachable!() +} +/// Performs a volatile store to the `dst` pointer. +/// +/// The stabilized version of this intrinsic is [`core::ptr::write_volatile`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn volatile_store(_dst: *mut T, _val: T) { + unreachable!() +} + +/// Performs a volatile load from the `src` pointer +/// The pointer is not required to be aligned. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +#[rustc_diagnostic_item = "intrinsics_unaligned_volatile_load"] +pub unsafe fn unaligned_volatile_load(_src: *const T) -> T { + unreachable!() +} +/// Performs a volatile store to the `dst` pointer. +/// The pointer is not required to be aligned. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +#[rustc_diagnostic_item = "intrinsics_unaligned_volatile_store"] +pub unsafe fn unaligned_volatile_store(_dst: *mut T, _val: T) { + unreachable!() +} + +/// Returns the square root of an `f16` +/// +/// The stabilized version of this intrinsic is +/// [`f16::sqrt`](../../std/primitive.f16.html#method.sqrt) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn sqrtf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the square root of an `f32` +/// +/// The stabilized version of this intrinsic is +/// [`f32::sqrt`](../../std/primitive.f32.html#method.sqrt) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn sqrtf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the square root of an `f64` +/// +/// The stabilized version of this intrinsic is +/// [`f64::sqrt`](../../std/primitive.f64.html#method.sqrt) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn sqrtf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the square root of an `f128` +/// +/// The stabilized version of this intrinsic is +/// [`f128::sqrt`](../../std/primitive.f128.html#method.sqrt) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn sqrtf128(_x: f128) -> f128 { + unreachable!() +} + +/// Raises an `f16` to an integer power. +/// +/// The stabilized version of this intrinsic is +/// [`f16::powi`](../../std/primitive.f16.html#method.powi) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn powif16(_a: f16, _x: i32) -> f16 { + unreachable!() +} +/// Raises an `f32` to an integer power. +/// +/// The stabilized version of this intrinsic is +/// [`f32::powi`](../../std/primitive.f32.html#method.powi) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn powif32(_a: f32, _x: i32) -> f32 { + unreachable!() +} +/// Raises an `f64` to an integer power. +/// +/// The stabilized version of this intrinsic is +/// [`f64::powi`](../../std/primitive.f64.html#method.powi) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn powif64(_a: f64, _x: i32) -> f64 { + unreachable!() +} +/// Raises an `f128` to an integer power. +/// +/// The stabilized version of this intrinsic is +/// [`f128::powi`](../../std/primitive.f128.html#method.powi) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn powif128(_a: f128, _x: i32) -> f128 { + unreachable!() +} + +/// Returns the sine of an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::sin`](../../std/primitive.f16.html#method.sin) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn sinf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the sine of an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::sin`](../../std/primitive.f32.html#method.sin) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn sinf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the sine of an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::sin`](../../std/primitive.f64.html#method.sin) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn sinf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the sine of an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::sin`](../../std/primitive.f128.html#method.sin) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn sinf128(_x: f128) -> f128 { + unreachable!() +} + +/// Returns the cosine of an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::cos`](../../std/primitive.f16.html#method.cos) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn cosf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the cosine of an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::cos`](../../std/primitive.f32.html#method.cos) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn cosf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the cosine of an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::cos`](../../std/primitive.f64.html#method.cos) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn cosf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the cosine of an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::cos`](../../std/primitive.f128.html#method.cos) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn cosf128(_x: f128) -> f128 { + unreachable!() +} + +/// Raises an `f16` to an `f16` power. +/// +/// The stabilized version of this intrinsic is +/// [`f16::powf`](../../std/primitive.f16.html#method.powf) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn powf16(_a: f16, _x: f16) -> f16 { + unreachable!() +} +/// Raises an `f32` to an `f32` power. +/// +/// The stabilized version of this intrinsic is +/// [`f32::powf`](../../std/primitive.f32.html#method.powf) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn powf32(_a: f32, _x: f32) -> f32 { + unreachable!() +} +/// Raises an `f64` to an `f64` power. +/// +/// The stabilized version of this intrinsic is +/// [`f64::powf`](../../std/primitive.f64.html#method.powf) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn powf64(_a: f64, _x: f64) -> f64 { + unreachable!() +} +/// Raises an `f128` to an `f128` power. +/// +/// The stabilized version of this intrinsic is +/// [`f128::powf`](../../std/primitive.f128.html#method.powf) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn powf128(_a: f128, _x: f128) -> f128 { + unreachable!() +} + +/// Returns the exponential of an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::exp`](../../std/primitive.f16.html#method.exp) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn expf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the exponential of an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::exp`](../../std/primitive.f32.html#method.exp) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn expf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the exponential of an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::exp`](../../std/primitive.f64.html#method.exp) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn expf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the exponential of an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::exp`](../../std/primitive.f128.html#method.exp) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn expf128(_x: f128) -> f128 { + unreachable!() +} + +/// Returns 2 raised to the power of an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::exp2`](../../std/primitive.f16.html#method.exp2) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn exp2f16(_x: f16) -> f16 { + unreachable!() +} +/// Returns 2 raised to the power of an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::exp2`](../../std/primitive.f32.html#method.exp2) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn exp2f32(_x: f32) -> f32 { + unreachable!() +} +/// Returns 2 raised to the power of an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::exp2`](../../std/primitive.f64.html#method.exp2) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn exp2f64(_x: f64) -> f64 { + unreachable!() +} +/// Returns 2 raised to the power of an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::exp2`](../../std/primitive.f128.html#method.exp2) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn exp2f128(_x: f128) -> f128 { + unreachable!() +} + +/// Returns the natural logarithm of an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::ln`](../../std/primitive.f16.html#method.ln) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn logf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the natural logarithm of an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::ln`](../../std/primitive.f32.html#method.ln) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn logf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the natural logarithm of an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::ln`](../../std/primitive.f64.html#method.ln) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn logf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the natural logarithm of an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::ln`](../../std/primitive.f128.html#method.ln) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn logf128(_x: f128) -> f128 { + unreachable!() +} + +/// Returns the base 10 logarithm of an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::log10`](../../std/primitive.f16.html#method.log10) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn log10f16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the base 10 logarithm of an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::log10`](../../std/primitive.f32.html#method.log10) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn log10f32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the base 10 logarithm of an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::log10`](../../std/primitive.f64.html#method.log10) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn log10f64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the base 10 logarithm of an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::log10`](../../std/primitive.f128.html#method.log10) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn log10f128(_x: f128) -> f128 { + unreachable!() +} + +/// Returns the base 2 logarithm of an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::log2`](../../std/primitive.f16.html#method.log2) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn log2f16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the base 2 logarithm of an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::log2`](../../std/primitive.f32.html#method.log2) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn log2f32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the base 2 logarithm of an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::log2`](../../std/primitive.f64.html#method.log2) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn log2f64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the base 2 logarithm of an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::log2`](../../std/primitive.f128.html#method.log2) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn log2f128(_x: f128) -> f128 { + unreachable!() +} + +/// Returns `a * b + c` for `f16` values. +/// +/// The stabilized version of this intrinsic is +/// [`f16::mul_add`](../../std/primitive.f16.html#method.mul_add) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fmaf16(_a: f16, _b: f16, _c: f16) -> f16 { + unreachable!() +} +/// Returns `a * b + c` for `f32` values. +/// +/// The stabilized version of this intrinsic is +/// [`f32::mul_add`](../../std/primitive.f32.html#method.mul_add) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fmaf32(_a: f32, _b: f32, _c: f32) -> f32 { + unreachable!() +} +/// Returns `a * b + c` for `f64` values. +/// +/// The stabilized version of this intrinsic is +/// [`f64::mul_add`](../../std/primitive.f64.html#method.mul_add) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fmaf64(_a: f64, _b: f64, _c: f64) -> f64 { + unreachable!() +} +/// Returns `a * b + c` for `f128` values. +/// +/// The stabilized version of this intrinsic is +/// [`f128::mul_add`](../../std/primitive.f128.html#method.mul_add) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fmaf128(_a: f128, _b: f128, _c: f128) -> f128 { + unreachable!() +} + +/// Returns `a * b + c` for `f16` values, non-deterministically executing +/// either a fused multiply-add or two operations with rounding of the +/// intermediate result. +/// +/// The operation is fused if the code generator determines that target +/// instruction set has support for a fused operation, and that the fused +/// operation is more efficient than the equivalent, separate pair of mul +/// and add instructions. It is unspecified whether or not a fused operation +/// is selected, and that may depend on optimization level and context, for +/// example. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fmuladdf16(_a: f16, _b: f16, _c: f16) -> f16 { + unreachable!() +} +/// Returns `a * b + c` for `f32` values, non-deterministically executing +/// either a fused multiply-add or two operations with rounding of the +/// intermediate result. +/// +/// The operation is fused if the code generator determines that target +/// instruction set has support for a fused operation, and that the fused +/// operation is more efficient than the equivalent, separate pair of mul +/// and add instructions. It is unspecified whether or not a fused operation +/// is selected, and that may depend on optimization level and context, for +/// example. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fmuladdf32(_a: f32, _b: f32, _c: f32) -> f32 { + unreachable!() +} +/// Returns `a * b + c` for `f64` values, non-deterministically executing +/// either a fused multiply-add or two operations with rounding of the +/// intermediate result. +/// +/// The operation is fused if the code generator determines that target +/// instruction set has support for a fused operation, and that the fused +/// operation is more efficient than the equivalent, separate pair of mul +/// and add instructions. It is unspecified whether or not a fused operation +/// is selected, and that may depend on optimization level and context, for +/// example. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fmuladdf64(_a: f64, _b: f64, _c: f64) -> f64 { + unreachable!() +} +/// Returns `a * b + c` for `f128` values, non-deterministically executing +/// either a fused multiply-add or two operations with rounding of the +/// intermediate result. +/// +/// The operation is fused if the code generator determines that target +/// instruction set has support for a fused operation, and that the fused +/// operation is more efficient than the equivalent, separate pair of mul +/// and add instructions. It is unspecified whether or not a fused operation +/// is selected, and that may depend on optimization level and context, for +/// example. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fmuladdf128(_a: f128, _b: f128, _c: f128) -> f128 { + unreachable!() +} + +/// Returns the largest integer less than or equal to an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::floor`](../../std/primitive.f16.html#method.floor) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn floorf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the largest integer less than or equal to an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::floor`](../../std/primitive.f32.html#method.floor) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn floorf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the largest integer less than or equal to an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::floor`](../../std/primitive.f64.html#method.floor) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn floorf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the largest integer less than or equal to an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::floor`](../../std/primitive.f128.html#method.floor) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn floorf128(_x: f128) -> f128 { + unreachable!() +} + +/// Returns the smallest integer greater than or equal to an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::ceil`](../../std/primitive.f16.html#method.ceil) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn ceilf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the smallest integer greater than or equal to an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::ceil`](../../std/primitive.f32.html#method.ceil) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn ceilf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the smallest integer greater than or equal to an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::ceil`](../../std/primitive.f64.html#method.ceil) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn ceilf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the smallest integer greater than or equal to an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::ceil`](../../std/primitive.f128.html#method.ceil) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn ceilf128(_x: f128) -> f128 { + unreachable!() +} + +/// Returns the integer part of an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::trunc`](../../std/primitive.f16.html#method.trunc) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn truncf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the integer part of an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::trunc`](../../std/primitive.f32.html#method.trunc) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn truncf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the integer part of an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::trunc`](../../std/primitive.f64.html#method.trunc) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn truncf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the integer part of an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::trunc`](../../std/primitive.f128.html#method.trunc) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn truncf128(_x: f128) -> f128 { + unreachable!() +} + +/// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust, +/// so this rounds half-way cases to the number with an even least significant digit. +/// +/// May raise an inexact floating-point exception if the argument is not an integer. +/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions +/// cannot actually be utilized from Rust code. +/// In other words, this intrinsic is equivalent in behavior to `nearbyintf16` and `roundevenf16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn rintf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust, +/// so this rounds half-way cases to the number with an even least significant digit. +/// +/// May raise an inexact floating-point exception if the argument is not an integer. +/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions +/// cannot actually be utilized from Rust code. +/// In other words, this intrinsic is equivalent in behavior to `nearbyintf32` and `roundevenf32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn rintf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust, +/// so this rounds half-way cases to the number with an even least significant digit. +/// +/// May raise an inexact floating-point exception if the argument is not an integer. +/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions +/// cannot actually be utilized from Rust code. +/// In other words, this intrinsic is equivalent in behavior to `nearbyintf64` and `roundevenf64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn rintf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust, +/// so this rounds half-way cases to the number with an even least significant digit. +/// +/// May raise an inexact floating-point exception if the argument is not an integer. +/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions +/// cannot actually be utilized from Rust code. +/// In other words, this intrinsic is equivalent in behavior to `nearbyintf128` and `roundevenf128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn rintf128(_x: f128) -> f128 { + unreachable!() +} + +/// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust, +/// so this rounds half-way cases to the number with an even least significant digit. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn nearbyintf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust, +/// so this rounds half-way cases to the number with an even least significant digit. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn nearbyintf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust, +/// so this rounds half-way cases to the number with an even least significant digit. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn nearbyintf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust, +/// so this rounds half-way cases to the number with an even least significant digit. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn nearbyintf128(_x: f128) -> f128 { + unreachable!() +} + +/// Returns the nearest integer to an `f16`. Rounds half-way cases away from zero. +/// +/// The stabilized version of this intrinsic is +/// [`f16::round`](../../std/primitive.f16.html#method.round) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn roundf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the nearest integer to an `f32`. Rounds half-way cases away from zero. +/// +/// The stabilized version of this intrinsic is +/// [`f32::round`](../../std/primitive.f32.html#method.round) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn roundf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the nearest integer to an `f64`. Rounds half-way cases away from zero. +/// +/// The stabilized version of this intrinsic is +/// [`f64::round`](../../std/primitive.f64.html#method.round) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn roundf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the nearest integer to an `f128`. Rounds half-way cases away from zero. +/// +/// The stabilized version of this intrinsic is +/// [`f128::round`](../../std/primitive.f128.html#method.round) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn roundf128(_x: f128) -> f128 { + unreachable!() +} + +/// Returns the nearest integer to an `f16`. Rounds half-way cases to the number +/// with an even least significant digit. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn roundevenf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the nearest integer to an `f32`. Rounds half-way cases to the number +/// with an even least significant digit. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn roundevenf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the nearest integer to an `f64`. Rounds half-way cases to the number +/// with an even least significant digit. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn roundevenf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the nearest integer to an `f128`. Rounds half-way cases to the number +/// with an even least significant digit. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn roundevenf128(_x: f128) -> f128 { + unreachable!() +} + +/// Float addition that allows optimizations based on algebraic rules. +/// May assume inputs are finite. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fadd_fast(_a: T, _b: T) -> T { unreachable!() } -/// Like [`transmute`], but even less checked at compile-time: rather than -/// giving an error for `size_of::() != size_of::()`, it's -/// **Undefined Behavior** at runtime. -/// -/// Prefer normal `transmute` where possible, for the extra checking, since -/// both do exactly the same thing at runtime, if they both compile. +/// Float subtraction that allows optimizations based on algebraic rules. +/// May assume inputs are finite. /// -/// This is not expected to ever be exposed directly to users, rather it -/// may eventually be exposed through some more-constrained API. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_transmute", since = "1.56.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] -#[rustc_nounwind] +/// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] -pub const unsafe fn transmute_unchecked(_src: Src) -> Dst { +#[rustc_nounwind] +pub unsafe fn fsub_fast(_a: T, _b: T) -> T { unreachable!() } -/// Returns `true` if the actual type given as `T` requires drop -/// glue; returns `false` if the actual type provided for `T` -/// implements `Copy`. -/// -/// If the actual type neither requires drop glue nor implements -/// `Copy`, then the return value of this function is unspecified. -/// -/// Note that, unlike most intrinsics, this is safe to call; -/// it does not require an `unsafe` block. -/// Therefore, implementations must not require the user to uphold -/// any safety invariants. +/// Float multiplication that allows optimizations based on algebraic rules. +/// May assume inputs are finite. /// -/// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop). -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_needs_drop", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] -#[rustc_nounwind] +/// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] -pub const fn needs_drop() -> bool { +#[rustc_nounwind] +pub unsafe fn fmul_fast(_a: T, _b: T) -> T { unreachable!() } -/// Calculates the offset from a pointer. -/// -/// This is implemented as an intrinsic to avoid converting to and from an -/// integer, since the conversion would throw away aliasing information. -/// -/// This can only be used with `Ptr` as a raw pointer type (`*mut` or `*const`) -/// to a `Sized` pointee and with `Delta` as `usize` or `isize`. Any other -/// instantiations may arbitrarily misbehave, and that's *not* a compiler bug. -/// -/// # Safety -/// -/// If the computed offset is non-zero, then both the starting and resulting pointer must be -/// either in bounds or at the end of an allocated object. If either pointer is out -/// of bounds or arithmetic overflow occurs then this operation is undefined behavior. +/// Float division that allows optimizations based on algebraic rules. +/// May assume inputs are finite. /// -/// The stabilized version of this intrinsic is [`pointer::offset`]. -#[must_use = "returns a new pointer rather than modifying its argument"] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] -#[rustc_nounwind] +/// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] -pub const unsafe fn offset(_dst: Ptr, _offset: Delta) -> Ptr { +#[rustc_nounwind] +pub unsafe fn fdiv_fast(_a: T, _b: T) -> T { unreachable!() } -/// Calculates the offset from a pointer, potentially wrapping. -/// -/// This is implemented as an intrinsic to avoid converting to and from an -/// integer, since the conversion inhibits certain optimizations. -/// -/// # Safety -/// -/// Unlike the `offset` intrinsic, this intrinsic does not restrict the -/// resulting pointer to point into or at the end of an allocated -/// object, and it wraps with two's complement arithmetic. The resulting -/// value is not necessarily valid to be used to actually access memory. +/// Float remainder that allows optimizations based on algebraic rules. +/// May assume inputs are finite. /// -/// The stabilized version of this intrinsic is [`pointer::wrapping_offset`]. -#[must_use = "returns a new pointer rather than modifying its argument"] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] -#[rustc_nounwind] +/// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] -pub const unsafe fn arith_offset(_dst: *const T, _offset: isize) -> *const T { +#[rustc_nounwind] +pub unsafe fn frem_fast(_a: T, _b: T) -> T { unreachable!() } -/// Masks out bits of the pointer according to a mask. -/// -/// Note that, unlike most intrinsics, this is safe to call; -/// it does not require an `unsafe` block. -/// Therefore, implementations must not require the user to uphold -/// any safety invariants. +/// Converts with LLVM’s fptoui/fptosi, which may return undef for values out of range +/// () /// -/// Consider using [`pointer::mask`] instead. -#[rustc_nounwind] +/// Stabilized as [`f32::to_int_unchecked`] and [`f64::to_int_unchecked`]. #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] -pub fn ptr_mask(_ptr: *const T, _mask: usize) -> *const T { +#[rustc_nounwind] +pub unsafe fn float_to_int_unchecked(_value: Float) -> Int { unreachable!() } -extern "rust-intrinsic" { - /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with - /// a size of `count` * `size_of::()` and an alignment of - /// `min_align_of::()` - /// - /// The volatile parameter is set to `true`, so it will not be optimized out - /// unless size is equal to zero. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn volatile_copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: usize); - /// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with - /// a size of `count * size_of::()` and an alignment of - /// `min_align_of::()` - /// - /// The volatile parameter is set to `true`, so it will not be optimized out - /// unless size is equal to zero. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn volatile_copy_memory(dst: *mut T, src: *const T, count: usize); - /// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a - /// size of `count * size_of::()` and an alignment of - /// `min_align_of::()`. - /// - /// The volatile parameter is set to `true`, so it will not be optimized out - /// unless size is equal to zero. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn volatile_set_memory(dst: *mut T, val: u8, count: usize); - - /// Performs a volatile load from the `src` pointer. - /// - /// The stabilized version of this intrinsic is [`core::ptr::read_volatile`]. - #[rustc_nounwind] - pub fn volatile_load(src: *const T) -> T; - /// Performs a volatile store to the `dst` pointer. - /// - /// The stabilized version of this intrinsic is [`core::ptr::write_volatile`]. - #[rustc_nounwind] - pub fn volatile_store(dst: *mut T, val: T); - - /// Performs a volatile load from the `src` pointer - /// The pointer is not required to be aligned. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - #[rustc_diagnostic_item = "intrinsics_unaligned_volatile_load"] - pub fn unaligned_volatile_load(src: *const T) -> T; - /// Performs a volatile store to the `dst` pointer. - /// The pointer is not required to be aligned. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - #[rustc_diagnostic_item = "intrinsics_unaligned_volatile_store"] - pub fn unaligned_volatile_store(dst: *mut T, val: T); - - /// Returns the square root of an `f16` - /// - /// The stabilized version of this intrinsic is - /// [`f16::sqrt`](../../std/primitive.f16.html#method.sqrt) - #[rustc_nounwind] - pub fn sqrtf16(x: f16) -> f16; - /// Returns the square root of an `f32` - /// - /// The stabilized version of this intrinsic is - /// [`f32::sqrt`](../../std/primitive.f32.html#method.sqrt) - #[rustc_nounwind] - pub fn sqrtf32(x: f32) -> f32; - /// Returns the square root of an `f64` - /// - /// The stabilized version of this intrinsic is - /// [`f64::sqrt`](../../std/primitive.f64.html#method.sqrt) - #[rustc_nounwind] - pub fn sqrtf64(x: f64) -> f64; - /// Returns the square root of an `f128` - /// - /// The stabilized version of this intrinsic is - /// [`f128::sqrt`](../../std/primitive.f128.html#method.sqrt) - #[rustc_nounwind] - pub fn sqrtf128(x: f128) -> f128; - - /// Raises an `f16` to an integer power. - /// - /// The stabilized version of this intrinsic is - /// [`f16::powi`](../../std/primitive.f16.html#method.powi) - #[rustc_nounwind] - pub fn powif16(a: f16, x: i32) -> f16; - /// Raises an `f32` to an integer power. - /// - /// The stabilized version of this intrinsic is - /// [`f32::powi`](../../std/primitive.f32.html#method.powi) - #[rustc_nounwind] - pub fn powif32(a: f32, x: i32) -> f32; - /// Raises an `f64` to an integer power. - /// - /// The stabilized version of this intrinsic is - /// [`f64::powi`](../../std/primitive.f64.html#method.powi) - #[rustc_nounwind] - pub fn powif64(a: f64, x: i32) -> f64; - /// Raises an `f128` to an integer power. - /// - /// The stabilized version of this intrinsic is - /// [`f128::powi`](../../std/primitive.f128.html#method.powi) - #[rustc_nounwind] - pub fn powif128(a: f128, x: i32) -> f128; - - /// Returns the sine of an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::sin`](../../std/primitive.f16.html#method.sin) - #[rustc_nounwind] - pub fn sinf16(x: f16) -> f16; - /// Returns the sine of an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::sin`](../../std/primitive.f32.html#method.sin) - #[rustc_nounwind] - pub fn sinf32(x: f32) -> f32; - /// Returns the sine of an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::sin`](../../std/primitive.f64.html#method.sin) - #[rustc_nounwind] - pub fn sinf64(x: f64) -> f64; - /// Returns the sine of an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::sin`](../../std/primitive.f128.html#method.sin) - #[rustc_nounwind] - pub fn sinf128(x: f128) -> f128; - - /// Returns the cosine of an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::cos`](../../std/primitive.f16.html#method.cos) - #[rustc_nounwind] - pub fn cosf16(x: f16) -> f16; - /// Returns the cosine of an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::cos`](../../std/primitive.f32.html#method.cos) - #[rustc_nounwind] - pub fn cosf32(x: f32) -> f32; - /// Returns the cosine of an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::cos`](../../std/primitive.f64.html#method.cos) - #[rustc_nounwind] - pub fn cosf64(x: f64) -> f64; - /// Returns the cosine of an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::cos`](../../std/primitive.f128.html#method.cos) - #[rustc_nounwind] - pub fn cosf128(x: f128) -> f128; - - /// Raises an `f16` to an `f16` power. - /// - /// The stabilized version of this intrinsic is - /// [`f16::powf`](../../std/primitive.f16.html#method.powf) - #[rustc_nounwind] - pub fn powf16(a: f16, x: f16) -> f16; - /// Raises an `f32` to an `f32` power. - /// - /// The stabilized version of this intrinsic is - /// [`f32::powf`](../../std/primitive.f32.html#method.powf) - #[rustc_nounwind] - pub fn powf32(a: f32, x: f32) -> f32; - /// Raises an `f64` to an `f64` power. - /// - /// The stabilized version of this intrinsic is - /// [`f64::powf`](../../std/primitive.f64.html#method.powf) - #[rustc_nounwind] - pub fn powf64(a: f64, x: f64) -> f64; - /// Raises an `f128` to an `f128` power. - /// - /// The stabilized version of this intrinsic is - /// [`f128::powf`](../../std/primitive.f128.html#method.powf) - #[rustc_nounwind] - pub fn powf128(a: f128, x: f128) -> f128; - - /// Returns the exponential of an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::exp`](../../std/primitive.f16.html#method.exp) - #[rustc_nounwind] - pub fn expf16(x: f16) -> f16; - /// Returns the exponential of an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::exp`](../../std/primitive.f32.html#method.exp) - #[rustc_nounwind] - pub fn expf32(x: f32) -> f32; - /// Returns the exponential of an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::exp`](../../std/primitive.f64.html#method.exp) - #[rustc_nounwind] - pub fn expf64(x: f64) -> f64; - /// Returns the exponential of an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::exp`](../../std/primitive.f128.html#method.exp) - #[rustc_nounwind] - pub fn expf128(x: f128) -> f128; - - /// Returns 2 raised to the power of an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::exp2`](../../std/primitive.f16.html#method.exp2) - #[rustc_nounwind] - pub fn exp2f16(x: f16) -> f16; - /// Returns 2 raised to the power of an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::exp2`](../../std/primitive.f32.html#method.exp2) - #[rustc_nounwind] - pub fn exp2f32(x: f32) -> f32; - /// Returns 2 raised to the power of an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::exp2`](../../std/primitive.f64.html#method.exp2) - #[rustc_nounwind] - pub fn exp2f64(x: f64) -> f64; - /// Returns 2 raised to the power of an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::exp2`](../../std/primitive.f128.html#method.exp2) - #[rustc_nounwind] - pub fn exp2f128(x: f128) -> f128; - - /// Returns the natural logarithm of an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::ln`](../../std/primitive.f16.html#method.ln) - #[rustc_nounwind] - pub fn logf16(x: f16) -> f16; - /// Returns the natural logarithm of an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::ln`](../../std/primitive.f32.html#method.ln) - #[rustc_nounwind] - pub fn logf32(x: f32) -> f32; - /// Returns the natural logarithm of an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::ln`](../../std/primitive.f64.html#method.ln) - #[rustc_nounwind] - pub fn logf64(x: f64) -> f64; - /// Returns the natural logarithm of an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::ln`](../../std/primitive.f128.html#method.ln) - #[rustc_nounwind] - pub fn logf128(x: f128) -> f128; - - /// Returns the base 10 logarithm of an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::log10`](../../std/primitive.f16.html#method.log10) - #[rustc_nounwind] - pub fn log10f16(x: f16) -> f16; - /// Returns the base 10 logarithm of an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::log10`](../../std/primitive.f32.html#method.log10) - #[rustc_nounwind] - pub fn log10f32(x: f32) -> f32; - /// Returns the base 10 logarithm of an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::log10`](../../std/primitive.f64.html#method.log10) - #[rustc_nounwind] - pub fn log10f64(x: f64) -> f64; - /// Returns the base 10 logarithm of an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::log10`](../../std/primitive.f128.html#method.log10) - #[rustc_nounwind] - pub fn log10f128(x: f128) -> f128; - - /// Returns the base 2 logarithm of an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::log2`](../../std/primitive.f16.html#method.log2) - #[rustc_nounwind] - pub fn log2f16(x: f16) -> f16; - /// Returns the base 2 logarithm of an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::log2`](../../std/primitive.f32.html#method.log2) - #[rustc_nounwind] - pub fn log2f32(x: f32) -> f32; - /// Returns the base 2 logarithm of an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::log2`](../../std/primitive.f64.html#method.log2) - #[rustc_nounwind] - pub fn log2f64(x: f64) -> f64; - /// Returns the base 2 logarithm of an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::log2`](../../std/primitive.f128.html#method.log2) - #[rustc_nounwind] - pub fn log2f128(x: f128) -> f128; - - /// Returns `a * b + c` for `f16` values. - /// - /// The stabilized version of this intrinsic is - /// [`f16::mul_add`](../../std/primitive.f16.html#method.mul_add) - #[rustc_nounwind] - pub fn fmaf16(a: f16, b: f16, c: f16) -> f16; - /// Returns `a * b + c` for `f32` values. - /// - /// The stabilized version of this intrinsic is - /// [`f32::mul_add`](../../std/primitive.f32.html#method.mul_add) - #[rustc_nounwind] - pub fn fmaf32(a: f32, b: f32, c: f32) -> f32; - /// Returns `a * b + c` for `f64` values. - /// - /// The stabilized version of this intrinsic is - /// [`f64::mul_add`](../../std/primitive.f64.html#method.mul_add) - #[rustc_nounwind] - pub fn fmaf64(a: f64, b: f64, c: f64) -> f64; - /// Returns `a * b + c` for `f128` values. - /// - /// The stabilized version of this intrinsic is - /// [`f128::mul_add`](../../std/primitive.f128.html#method.mul_add) - #[rustc_nounwind] - pub fn fmaf128(a: f128, b: f128, c: f128) -> f128; - - /// Returns `a * b + c` for `f16` values, non-deterministically executing - /// either a fused multiply-add or two operations with rounding of the - /// intermediate result. - /// - /// The operation is fused if the code generator determines that target - /// instruction set has support for a fused operation, and that the fused - /// operation is more efficient than the equivalent, separate pair of mul - /// and add instructions. It is unspecified whether or not a fused operation - /// is selected, and that may depend on optimization level and context, for - /// example. - #[rustc_nounwind] - pub fn fmuladdf16(a: f16, b: f16, c: f16) -> f16; - /// Returns `a * b + c` for `f32` values, non-deterministically executing - /// either a fused multiply-add or two operations with rounding of the - /// intermediate result. - /// - /// The operation is fused if the code generator determines that target - /// instruction set has support for a fused operation, and that the fused - /// operation is more efficient than the equivalent, separate pair of mul - /// and add instructions. It is unspecified whether or not a fused operation - /// is selected, and that may depend on optimization level and context, for - /// example. - #[rustc_nounwind] - pub fn fmuladdf32(a: f32, b: f32, c: f32) -> f32; - /// Returns `a * b + c` for `f64` values, non-deterministically executing - /// either a fused multiply-add or two operations with rounding of the - /// intermediate result. - /// - /// The operation is fused if the code generator determines that target - /// instruction set has support for a fused operation, and that the fused - /// operation is more efficient than the equivalent, separate pair of mul - /// and add instructions. It is unspecified whether or not a fused operation - /// is selected, and that may depend on optimization level and context, for - /// example. - #[rustc_nounwind] - pub fn fmuladdf64(a: f64, b: f64, c: f64) -> f64; - /// Returns `a * b + c` for `f128` values, non-deterministically executing - /// either a fused multiply-add or two operations with rounding of the - /// intermediate result. - /// - /// The operation is fused if the code generator determines that target - /// instruction set has support for a fused operation, and that the fused - /// operation is more efficient than the equivalent, separate pair of mul - /// and add instructions. It is unspecified whether or not a fused operation - /// is selected, and that may depend on optimization level and context, for - /// example. - #[rustc_nounwind] - pub fn fmuladdf128(a: f128, b: f128, c: f128) -> f128; - - /// Returns the largest integer less than or equal to an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::floor`](../../std/primitive.f16.html#method.floor) - #[rustc_nounwind] - pub fn floorf16(x: f16) -> f16; - /// Returns the largest integer less than or equal to an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::floor`](../../std/primitive.f32.html#method.floor) - #[rustc_nounwind] - pub fn floorf32(x: f32) -> f32; - /// Returns the largest integer less than or equal to an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::floor`](../../std/primitive.f64.html#method.floor) - #[rustc_nounwind] - pub fn floorf64(x: f64) -> f64; - /// Returns the largest integer less than or equal to an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::floor`](../../std/primitive.f128.html#method.floor) - #[rustc_nounwind] - pub fn floorf128(x: f128) -> f128; - - /// Returns the smallest integer greater than or equal to an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::ceil`](../../std/primitive.f16.html#method.ceil) - #[rustc_nounwind] - pub fn ceilf16(x: f16) -> f16; - /// Returns the smallest integer greater than or equal to an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::ceil`](../../std/primitive.f32.html#method.ceil) - #[rustc_nounwind] - pub fn ceilf32(x: f32) -> f32; - /// Returns the smallest integer greater than or equal to an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::ceil`](../../std/primitive.f64.html#method.ceil) - #[rustc_nounwind] - pub fn ceilf64(x: f64) -> f64; - /// Returns the smallest integer greater than or equal to an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::ceil`](../../std/primitive.f128.html#method.ceil) - #[rustc_nounwind] - pub fn ceilf128(x: f128) -> f128; - - /// Returns the integer part of an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::trunc`](../../std/primitive.f16.html#method.trunc) - #[rustc_nounwind] - pub fn truncf16(x: f16) -> f16; - /// Returns the integer part of an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::trunc`](../../std/primitive.f32.html#method.trunc) - #[rustc_nounwind] - pub fn truncf32(x: f32) -> f32; - /// Returns the integer part of an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::trunc`](../../std/primitive.f64.html#method.trunc) - #[rustc_nounwind] - pub fn truncf64(x: f64) -> f64; - /// Returns the integer part of an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::trunc`](../../std/primitive.f128.html#method.trunc) - #[rustc_nounwind] - pub fn truncf128(x: f128) -> f128; - - /// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust, - /// so this rounds half-way cases to the number with an even least significant digit. - /// - /// May raise an inexact floating-point exception if the argument is not an integer. - /// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions - /// cannot actually be utilized from Rust code. - /// In other words, this intrinsic is equivalent in behavior to `nearbyintf16` and `roundevenf16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even) - #[rustc_nounwind] - pub fn rintf16(x: f16) -> f16; - /// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust, - /// so this rounds half-way cases to the number with an even least significant digit. - /// - /// May raise an inexact floating-point exception if the argument is not an integer. - /// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions - /// cannot actually be utilized from Rust code. - /// In other words, this intrinsic is equivalent in behavior to `nearbyintf32` and `roundevenf32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even) - #[rustc_nounwind] - pub fn rintf32(x: f32) -> f32; - /// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust, - /// so this rounds half-way cases to the number with an even least significant digit. - /// - /// May raise an inexact floating-point exception if the argument is not an integer. - /// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions - /// cannot actually be utilized from Rust code. - /// In other words, this intrinsic is equivalent in behavior to `nearbyintf64` and `roundevenf64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even) - #[rustc_nounwind] - pub fn rintf64(x: f64) -> f64; - /// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust, - /// so this rounds half-way cases to the number with an even least significant digit. - /// - /// May raise an inexact floating-point exception if the argument is not an integer. - /// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions - /// cannot actually be utilized from Rust code. - /// In other words, this intrinsic is equivalent in behavior to `nearbyintf128` and `roundevenf128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even) - #[rustc_nounwind] - pub fn rintf128(x: f128) -> f128; - - /// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust, - /// so this rounds half-way cases to the number with an even least significant digit. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn nearbyintf16(x: f16) -> f16; - /// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust, - /// so this rounds half-way cases to the number with an even least significant digit. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn nearbyintf32(x: f32) -> f32; - /// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust, - /// so this rounds half-way cases to the number with an even least significant digit. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn nearbyintf64(x: f64) -> f64; - /// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust, - /// so this rounds half-way cases to the number with an even least significant digit. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn nearbyintf128(x: f128) -> f128; - - /// Returns the nearest integer to an `f16`. Rounds half-way cases away from zero. - /// - /// The stabilized version of this intrinsic is - /// [`f16::round`](../../std/primitive.f16.html#method.round) - #[rustc_nounwind] - pub fn roundf16(x: f16) -> f16; - /// Returns the nearest integer to an `f32`. Rounds half-way cases away from zero. - /// - /// The stabilized version of this intrinsic is - /// [`f32::round`](../../std/primitive.f32.html#method.round) - #[rustc_nounwind] - pub fn roundf32(x: f32) -> f32; - /// Returns the nearest integer to an `f64`. Rounds half-way cases away from zero. - /// - /// The stabilized version of this intrinsic is - /// [`f64::round`](../../std/primitive.f64.html#method.round) - #[rustc_nounwind] - pub fn roundf64(x: f64) -> f64; - /// Returns the nearest integer to an `f128`. Rounds half-way cases away from zero. - /// - /// The stabilized version of this intrinsic is - /// [`f128::round`](../../std/primitive.f128.html#method.round) - #[rustc_nounwind] - pub fn roundf128(x: f128) -> f128; - - /// Returns the nearest integer to an `f16`. Rounds half-way cases to the number - /// with an even least significant digit. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn roundevenf16(x: f16) -> f16; - /// Returns the nearest integer to an `f32`. Rounds half-way cases to the number - /// with an even least significant digit. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn roundevenf32(x: f32) -> f32; - /// Returns the nearest integer to an `f64`. Rounds half-way cases to the number - /// with an even least significant digit. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn roundevenf64(x: f64) -> f64; - /// Returns the nearest integer to an `f128`. Rounds half-way cases to the number - /// with an even least significant digit. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn roundevenf128(x: f128) -> f128; - - /// Float addition that allows optimizations based on algebraic rules. - /// May assume inputs are finite. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn fadd_fast(a: T, b: T) -> T; - - /// Float subtraction that allows optimizations based on algebraic rules. - /// May assume inputs are finite. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn fsub_fast(a: T, b: T) -> T; - - /// Float multiplication that allows optimizations based on algebraic rules. - /// May assume inputs are finite. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn fmul_fast(a: T, b: T) -> T; - - /// Float division that allows optimizations based on algebraic rules. - /// May assume inputs are finite. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn fdiv_fast(a: T, b: T) -> T; - - /// Float remainder that allows optimizations based on algebraic rules. - /// May assume inputs are finite. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn frem_fast(a: T, b: T) -> T; - - /// Converts with LLVM’s fptoui/fptosi, which may return undef for values out of range - /// () - /// - /// Stabilized as [`f32::to_int_unchecked`] and [`f64::to_int_unchecked`]. - #[rustc_nounwind] - pub fn float_to_int_unchecked(value: Float) -> Int; -} - /// Float addition that allows optimizations based on algebraic rules. /// /// This intrinsic does not have a stable counterpart. @@ -2723,8 +3049,7 @@ pub fn frem_algebraic(_a: T, _b: T) -> T { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `count_ones` method. For example, /// [`u32::count_ones`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ctpop", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2768,8 +3093,7 @@ pub const fn ctpop(_x: T) -> u32 { /// let num_leading = ctlz(x); /// assert_eq!(num_leading, 16); /// ``` -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ctlz", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2794,8 +3118,7 @@ pub const fn ctlz(_x: T) -> u32 { /// let num_leading = unsafe { ctlz_nonzero(x) }; /// assert_eq!(num_leading, 3); /// ``` -#[cfg_attr(bootstrap, rustc_const_stable(feature = "constctlz", since = "1.50.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2839,8 +3162,7 @@ pub const unsafe fn ctlz_nonzero(_x: T) -> u32 { /// let num_trailing = cttz(x); /// assert_eq!(num_trailing, 16); /// ``` -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cttz", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2865,8 +3187,7 @@ pub const fn cttz(_x: T) -> u32 { /// let num_trailing = unsafe { cttz_nonzero(x) }; /// assert_eq!(num_trailing, 3); /// ``` -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cttz_nonzero", since = "1.53.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2884,8 +3205,7 @@ pub const unsafe fn cttz_nonzero(_x: T) -> u32 { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `swap_bytes` method. For example, /// [`u32::swap_bytes`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_bswap", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2903,8 +3223,7 @@ pub const fn bswap(_x: T) -> T { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `reverse_bits` method. For example, /// [`u32::reverse_bits`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_bitreverse", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2919,7 +3238,6 @@ pub const fn bitreverse(_x: T) -> T { /// large and difficult to optimize. /// /// The stabilized version of this intrinsic is [`Ord::cmp`]. -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_three_way_compare", issue = "none"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn three_way_compare(_lhs: T, _rhss: T) -> crate::cmp::Ordering { @@ -2936,8 +3254,7 @@ pub const fn three_way_compare(_lhs: T, _rhss: T) -> crate::cmp::Orderi /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `overflowing_add` method. For example, /// [`u32::overflowing_add`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_overflow", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2955,8 +3272,7 @@ pub const fn add_with_overflow(_x: T, _y: T) -> (T, bool) { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `overflowing_sub` method. For example, /// [`u32::overflowing_sub`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_overflow", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2974,8 +3290,7 @@ pub const fn sub_with_overflow(_x: T, _y: T) -> (T, bool) { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `overflowing_mul` method. For example, /// [`u32::overflowing_mul`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_overflow", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -2983,11 +3298,38 @@ pub const fn mul_with_overflow(_x: T, _y: T) -> (T, bool) { unimplemented!() } +/// Performs full-width multiplication and addition with a carry: +/// `multiplier * multiplicand + addend + carry`. +/// +/// This is possible without any overflow. For `uN`: +/// MAX * MAX + MAX + MAX +/// => (2ⁿ-1) × (2ⁿ-1) + (2ⁿ-1) + (2ⁿ-1) +/// => (2²ⁿ - 2ⁿ⁺¹ + 1) + (2ⁿ⁺¹ - 2) +/// => 2²ⁿ - 1 +/// +/// For `iN`, the upper bound is MIN * MIN + MAX + MAX => 2²ⁿ⁻² + 2ⁿ - 2, +/// and the lower bound is MAX * MIN + MIN + MIN => -2²ⁿ⁻² - 2ⁿ + 2ⁿ⁺¹. +/// +/// This currently supports unsigned integers *only*, no signed ones. +/// The stabilized versions of this intrinsic are available on integers. +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_const_unstable(feature = "const_carrying_mul_add", issue = "85532")] +#[rustc_nounwind] +#[rustc_intrinsic] +#[miri::intrinsic_fallback_is_spec] +pub const fn carrying_mul_add, U>( + multiplier: T, + multiplicand: T, + addend: T, + carry: T, +) -> (U, T) { + multiplier.carrying_mul_add(multiplicand, addend, carry) +} + /// Performs an exact division, resulting in undefined behavior where /// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1` /// /// This intrinsic does not have a stable counterpart. -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_exact_div", issue = "none"))] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3001,8 +3343,7 @@ pub const unsafe fn exact_div(_x: T, _y: T) -> T { /// Safe wrappers for this intrinsic are available on the integer /// primitives via the `checked_div` method. For example, /// [`u32::checked_div`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked_div", since = "1.52.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3015,8 +3356,7 @@ pub const unsafe fn unchecked_div(_x: T, _y: T) -> T { /// Safe wrappers for this intrinsic are available on the integer /// primitives via the `checked_rem` method. For example, /// [`u32::checked_rem`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked_rem", since = "1.52.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3030,8 +3370,7 @@ pub const unsafe fn unchecked_rem(_x: T, _y: T) -> T { /// Safe wrappers for this intrinsic are available on the integer /// primitives via the `checked_shl` method. For example, /// [`u32::checked_shl`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3044,8 +3383,7 @@ pub const unsafe fn unchecked_shl(_x: T, _y: U) -> T { /// Safe wrappers for this intrinsic are available on the integer /// primitives via the `checked_shr` method. For example, /// [`u32::checked_shr`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3058,8 +3396,7 @@ pub const unsafe fn unchecked_shr(_x: T, _y: U) -> T { /// /// The stable counterpart of this intrinsic is `unchecked_add` on the various /// integer types, such as [`u16::unchecked_add`] and [`i64::unchecked_add`]. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "unchecked_math", since = "1.79.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3072,8 +3409,7 @@ pub const unsafe fn unchecked_add(_x: T, _y: T) -> T { /// /// The stable counterpart of this intrinsic is `unchecked_sub` on the various /// integer types, such as [`u16::unchecked_sub`] and [`i64::unchecked_sub`]. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "unchecked_math", since = "1.79.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3086,8 +3422,7 @@ pub const unsafe fn unchecked_sub(_x: T, _y: T) -> T { /// /// The stable counterpart of this intrinsic is `unchecked_mul` on the various /// integer types, such as [`u16::unchecked_mul`] and [`i64::unchecked_mul`]. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "unchecked_math", since = "1.79.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3105,8 +3440,7 @@ pub const unsafe fn unchecked_mul(_x: T, _y: T) -> T { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `rotate_left` method. For example, /// [`u32::rotate_left`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_rotate", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3124,8 +3458,7 @@ pub const fn rotate_left(_x: T, _shift: u32) -> T { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `rotate_right` method. For example, /// [`u32::rotate_right`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_rotate", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3143,8 +3476,7 @@ pub const fn rotate_right(_x: T, _shift: u32) -> T { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `wrapping_add` method. For example, /// [`u32::wrapping_add`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3161,8 +3493,7 @@ pub const fn wrapping_add(_a: T, _b: T) -> T { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `wrapping_sub` method. For example, /// [`u32::wrapping_sub`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3179,8 +3510,7 @@ pub const fn wrapping_sub(_a: T, _b: T) -> T { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `wrapping_mul` method. For example, /// [`u32::wrapping_mul`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3198,8 +3528,7 @@ pub const fn wrapping_mul(_a: T, _b: T) -> T { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `saturating_add` method. For example, /// [`u32::saturating_add`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_saturating", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3216,8 +3545,7 @@ pub const fn saturating_add(_a: T, _b: T) -> T { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `saturating_sub` method. For example, /// [`u32::saturating_sub`] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_saturating", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3231,8 +3559,7 @@ pub const fn saturating_sub(_a: T, _b: T) -> T { /// This intrinsic can *only* be called where the pointer is a local without /// projections (`read_via_copy(ptr)`, not `read_via_copy(*ptr)`) so that it /// trivially obeys runtime-MIR rules about derefs in operands. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_read", since = "1.71.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3246,8 +3573,7 @@ pub const unsafe fn read_via_copy(_ptr: *const T) -> T { /// This intrinsic can *only* be called where the pointer is a local without /// projections (`write_via_move(ptr, x)`, not `write_via_move(*ptr, x)`) so /// that it trivially obeys runtime-MIR rules about derefs in operands. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_write", since = "1.83.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3264,8 +3590,7 @@ pub const unsafe fn write_via_move(_ptr: *mut T, _value: T) { /// any safety invariants. /// /// The stabilized version of this intrinsic is [`core::mem::discriminant`]. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_discriminant", since = "1.75.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3273,39 +3598,48 @@ pub const fn discriminant_value(_v: &T) -> ::Discrimin unimplemented!() } -extern "rust-intrinsic" { - /// Rust's "try catch" construct for unwinding. Invokes the function pointer `try_fn` with the - /// data pointer `data`, and calls `catch_fn` if unwinding occurs while `try_fn` runs. - /// - /// `catch_fn` must not unwind. - /// - /// The third argument is a function called if an unwind occurs (both Rust `panic` and foreign - /// unwinds). This function takes the data pointer and a pointer to the target- and - /// runtime-specific exception object that was caught. - /// - /// Note that in the case of a foreign unwinding operation, the exception object data may not be - /// safely usable from Rust, and should not be directly exposed via the standard library. To - /// prevent unsafe access, the library implementation may either abort the process or present an - /// opaque error type to the user. - /// - /// For more information, see the compiler's source, as well as the documentation for the stable - /// version of this intrinsic, `std::panic::catch_unwind`. - #[rustc_nounwind] - pub fn catch_unwind(try_fn: fn(*mut u8), data: *mut u8, catch_fn: fn(*mut u8, *mut u8)) -> i32; - - /// Emits a `nontemporal` store, which gives a hint to the CPU that the data should not be held - /// in cache. Except for performance, this is fully equivalent to `ptr.write(val)`. - /// - /// Not all architectures provide such an operation. For instance, x86 does not: while `MOVNT` - /// exists, that operation is *not* equivalent to `ptr.write(val)` (`MOVNT` writes can be reordered - /// in ways that are not allowed for regular writes). - #[rustc_nounwind] - pub fn nontemporal_store(ptr: *mut T, val: T); +/// Rust's "try catch" construct for unwinding. Invokes the function pointer `try_fn` with the +/// data pointer `data`, and calls `catch_fn` if unwinding occurs while `try_fn` runs. +/// +/// `catch_fn` must not unwind. +/// +/// The third argument is a function called if an unwind occurs (both Rust `panic` and foreign +/// unwinds). This function takes the data pointer and a pointer to the target- and +/// runtime-specific exception object that was caught. +/// +/// Note that in the case of a foreign unwinding operation, the exception object data may not be +/// safely usable from Rust, and should not be directly exposed via the standard library. To +/// prevent unsafe access, the library implementation may either abort the process or present an +/// opaque error type to the user. +/// +/// For more information, see the compiler's source, as well as the documentation for the stable +/// version of this intrinsic, `std::panic::catch_unwind`. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn catch_unwind( + _try_fn: fn(*mut u8), + _data: *mut u8, + _catch_fn: fn(*mut u8, *mut u8), +) -> i32 { + unreachable!() +} + +/// Emits a `nontemporal` store, which gives a hint to the CPU that the data should not be held +/// in cache. Except for performance, this is fully equivalent to `ptr.write(val)`. +/// +/// Not all architectures provide such an operation. For instance, x86 does not: while `MOVNT` +/// exists, that operation is *not* equivalent to `ptr.write(val)` (`MOVNT` writes can be reordered +/// in ways that are not allowed for regular writes). +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn nontemporal_store(_ptr: *mut T, _val: T) { + unreachable!() } /// See documentation of `<*const T>::offset_from` for details. -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_offset_from", since = "1.65.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3314,7 +3648,6 @@ pub const unsafe fn ptr_offset_from(_ptr: *const T, _base: *const T) -> isize } /// See documentation of `<*const T>::sub_ptr` for details. -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892"))] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3326,7 +3659,6 @@ pub const unsafe fn ptr_offset_from_unsigned(_ptr: *const T, _base: *const T) /// Returns `2` if the result is unknown. /// Returns `1` if the pointers are guaranteed equal. /// Returns `0` if the pointers are guaranteed inequal. -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020"))] #[rustc_intrinsic] #[rustc_nounwind] #[rustc_do_not_const_check] @@ -3359,7 +3691,6 @@ pub const fn ptr_guaranteed_cmp(ptr: *const T, other: *const T) -> u8 { /// /// (The implementation is allowed to branch on the results of comparisons, /// which is UB if any of their inputs are `undef`.) -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_intrinsic_raw_eq", issue = "none"))] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3381,10 +3712,6 @@ pub const unsafe fn raw_eq(_a: &T, _b: &T) -> bool { /// that differs. That allows optimizations that can read in large chunks. /// /// [valid]: crate::ptr#safety -#[cfg_attr( - bootstrap, - rustc_const_unstable(feature = "const_intrinsic_compare_bytes", issue = "none") -)] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3395,7 +3722,6 @@ pub const unsafe fn compare_bytes(_left: *const u8, _right: *const u8, _bytes: u /// See documentation of [`std::hint::black_box`] for details. /// /// [`std::hint::black_box`]: crate::hint::black_box -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_black_box", issue = "none"))] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -3490,7 +3816,7 @@ where /// See [`const_eval_select()`] for the rules and requirements around that intrinsic. pub(crate) macro const_eval_select { ( - @capture { $($arg:ident : $ty:ty = $val:expr),* $(,)? } $( -> $ret:ty )? : + @capture$([$($binders:tt)*])? { $($arg:ident : $ty:ty = $val:expr),* $(,)? } $( -> $ret:ty )? : if const $(#[$compiletime_attr:meta])* $compiletime:block else @@ -3498,7 +3824,7 @@ pub(crate) macro const_eval_select { ) => { // Use the `noinline` arm, after adding explicit `inline` attributes $crate::intrinsics::const_eval_select!( - @capture { $($arg : $ty = $val),* } $(-> $ret)? : + @capture$([$($binders)*])? { $($arg : $ty = $val),* } $(-> $ret)? : #[noinline] if const #[inline] // prevent codegen on this function @@ -3512,7 +3838,7 @@ pub(crate) macro const_eval_select { }, // With a leading #[noinline], we don't add inline attributes ( - @capture { $($arg:ident : $ty:ty = $val:expr),* $(,)? } $( -> $ret:ty )? : + @capture$([$($binders:tt)*])? { $($arg:ident : $ty:ty = $val:expr),* $(,)? } $( -> $ret:ty )? : #[noinline] if const $(#[$compiletime_attr:meta])* $compiletime:block @@ -3520,12 +3846,12 @@ pub(crate) macro const_eval_select { $(#[$runtime_attr:meta])* $runtime:block ) => {{ $(#[$runtime_attr])* - fn runtime($($arg: $ty),*) $( -> $ret )? { + fn runtime$(<$($binders)*>)?($($arg: $ty),*) $( -> $ret )? { $runtime } $(#[$compiletime_attr])* - const fn compiletime($($arg: $ty),*) $( -> $ret )? { + const fn compiletime$(<$($binders)*>)?($($arg: $ty),*) $( -> $ret )? { // Don't warn if one of the arguments is unused. $(let _ = $arg;)* @@ -3537,14 +3863,14 @@ pub(crate) macro const_eval_select { // We support leaving away the `val` expressions for *all* arguments // (but not for *some* arguments, that's too tricky). ( - @capture { $($arg:ident : $ty:ty),* $(,)? } $( -> $ret:ty )? : + @capture$([$($binders:tt)*])? { $($arg:ident : $ty:ty),* $(,)? } $( -> $ret:ty )? : if const $(#[$compiletime_attr:meta])* $compiletime:block else $(#[$runtime_attr:meta])* $runtime:block ) => { $crate::intrinsics::const_eval_select!( - @capture { $($arg : $ty = $arg),* } $(-> $ret)? : + @capture$([$($binders)*])? { $($arg : $ty = $arg),* } $(-> $ret)? : if const $(#[$compiletime_attr])* $compiletime else @@ -3627,11 +3953,7 @@ pub(crate) macro const_eval_select { /// # _ = foo(&5_i32); /// # _ = bar(&5_i32); /// ``` -#[cfg_attr( - bootstrap, - rustc_const_stable(feature = "const_is_val_statically_known", since = "CURRENT_RUSTC_VERSION") -)] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] +#[rustc_const_stable_indirect] #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] @@ -3652,9 +3974,9 @@ pub const fn is_val_statically_known(_arg: T) -> bool { #[rustc_nounwind] #[inline] #[rustc_intrinsic] -// Const-unstable because `swap_nonoverlapping` is const-unstable. -#[rustc_const_unstable(feature = "const_typed_swap", issue = "none")] -pub const unsafe fn typed_swap(x: *mut T, y: *mut T) { +#[rustc_intrinsic_const_stable_indirect] +#[rustc_allow_const_fn_unstable(const_swap_nonoverlapping)] // this is anyway not called since CTFE implements the intrinsic +pub const unsafe fn typed_swap_nonoverlapping(x: *mut T, y: *mut T) { // SAFETY: The caller provided single non-overlapping items behind // pointers, so swapping them with `count: 1` is fine. unsafe { ptr::swap_nonoverlapping(x, y, 1) }; @@ -3673,8 +3995,7 @@ pub const unsafe fn typed_swap(x: *mut T, y: *mut T) { /// assertions are enabled whenever the *user crate* has UB checks enabled. However, if the /// user has UB checks disabled, the checks will still get optimized out. This intrinsic is /// primarily used by [`ub_checks::assert_unsafe_precondition`]. -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_ub_checks", issue = "none"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] // just for UB checks +#[rustc_intrinsic_const_stable_indirect] // just for UB checks #[inline(always)] #[rustc_intrinsic] pub const fn ub_checks() -> bool { @@ -3757,8 +4078,7 @@ pub unsafe fn vtable_align(_ptr: *const ()) -> usize { /// The stabilized version of this intrinsic is [`core::mem::size_of`]. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_size_of", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn size_of() -> usize { @@ -3775,8 +4095,7 @@ pub const fn size_of() -> usize { /// The stabilized version of this intrinsic is [`core::mem::align_of`]. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_min_align_of", since = "1.40.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn min_align_of() -> usize { @@ -3789,7 +4108,6 @@ pub const fn min_align_of() -> usize { /// It's "tracking issue" is [#91971](https://github.com/rust-lang/rust/issues/91971). #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_pref_align_of", issue = "91971"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn pref_align_of() -> usize { @@ -3807,7 +4125,6 @@ pub const unsafe fn pref_align_of() -> usize { /// The to-be-stabilized version of this intrinsic is [`crate::mem::variant_count`]. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "variant_count", issue = "73662"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn variant_count() -> usize { @@ -3823,9 +4140,9 @@ pub const fn variant_count() -> usize { /// See [`crate::mem::size_of_val_raw`] for safety conditions. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_size_of_val", issue = "46571"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] +#[rustc_intrinsic_const_stable_indirect] pub const unsafe fn size_of_val(_ptr: *const T) -> usize { unreachable!() } @@ -3839,9 +4156,9 @@ pub const unsafe fn size_of_val(_ptr: *const T) -> usize { /// See [`crate::mem::align_of_val_raw`] for safety conditions. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_align_of_val", issue = "46571"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] +#[rustc_intrinsic_const_stable_indirect] pub const unsafe fn min_align_of_val(_ptr: *const T) -> usize { unreachable!() } @@ -3856,7 +4173,6 @@ pub const unsafe fn min_align_of_val(_ptr: *const T) -> usize { /// The stabilized version of this intrinsic is [`core::any::type_name`]. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_type_name", issue = "63084"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn type_name() -> &'static str { @@ -3875,7 +4191,6 @@ pub const fn type_name() -> &'static str { /// The stabilized version of this intrinsic is [`core::any::TypeId::of`]. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_type_id", issue = "77125"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn type_id() -> u128 { @@ -3889,8 +4204,7 @@ pub const fn type_id() -> u128 { /// change the possible layouts of pointers. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0"))] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn aggregate_raw_ptr, D, M>(_data: D, _meta: M) -> P { @@ -3915,11 +4229,7 @@ impl AggregateRawPtr<*mut T> for *mut P { /// This is used to implement functions like `ptr::metadata`. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg_attr( - bootstrap, - cfg_attr(bootstrap, rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0")) -)] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn ptr_metadata + ?Sized, M>(_ptr: *const P) -> M { @@ -4019,14 +4329,17 @@ pub const fn ptr_metadata + ?Sized, M>(_ptr: *cons /// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append #[doc(alias = "memcpy")] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_allowed_through_unstable_modules] +#[cfg_attr(bootstrap, rustc_allowed_through_unstable_modules)] +#[cfg_attr( + not(bootstrap), + rustc_allowed_through_unstable_modules = "import this function via `std::mem` instead" +)] #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_diagnostic_item = "ptr_copy_nonoverlapping"] pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize) { - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0"))] - #[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] + #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -4076,13 +4389,11 @@ pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: us /// /// Behavior is undefined if any of the following conditions are violated: /// -/// * `src` must be [valid] for reads of `count * size_of::()` bytes, and must remain valid even -/// when `dst` is written for `count * size_of::()` bytes. (This means if the memory ranges -/// overlap, the two pointers must not be subject to aliasing restrictions relative to each -/// other.) +/// * `src` must be [valid] for reads of `count * size_of::()` bytes. /// /// * `dst` must be [valid] for writes of `count * size_of::()` bytes, and must remain valid even -/// when `src` is read for `count * size_of::()` bytes. +/// when `src` is read for `count * size_of::()` bytes. (This means if the memory ranges +/// overlap, the `dst` pointer must not be invalidated by `src` reads.) /// /// * Both `src` and `dst` must be properly aligned. /// @@ -4126,14 +4437,17 @@ pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: us /// ``` #[doc(alias = "memmove")] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_allowed_through_unstable_modules] +#[cfg_attr(bootstrap, rustc_allowed_through_unstable_modules)] +#[cfg_attr( + not(bootstrap), + rustc_allowed_through_unstable_modules = "import this function via `std::mem` instead" +)] #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_diagnostic_item = "ptr_copy"] pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0"))] - #[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] + #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -4210,14 +4524,17 @@ pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { /// ``` #[doc(alias = "memset")] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_allowed_through_unstable_modules] +#[cfg_attr(bootstrap, rustc_allowed_through_unstable_modules)] +#[cfg_attr( + not(bootstrap), + rustc_allowed_through_unstable_modules = "import this function via `std::mem` instead" +)] #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_diagnostic_item = "ptr_write_bytes"] pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_write", since = "1.83.0"))] - #[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] + #[rustc_intrinsic_const_stable_indirect] #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] @@ -4250,7 +4567,6 @@ pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { /// The stabilized version of this intrinsic is /// [`f16::min`] #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f16", issue = "116909"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn minnumf16(_x: f16, _y: f16) -> f16 { @@ -4267,11 +4583,7 @@ pub const fn minnumf16(_x: f16, _y: f16) -> f16 { /// The stabilized version of this intrinsic is /// [`f32::min`] #[rustc_nounwind] -#[cfg_attr( - bootstrap, - rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION") -)] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn minnumf32(_x: f32, _y: f32) -> f32 { @@ -4288,11 +4600,7 @@ pub const fn minnumf32(_x: f32, _y: f32) -> f32 { /// The stabilized version of this intrinsic is /// [`f64::min`] #[rustc_nounwind] -#[cfg_attr( - bootstrap, - rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION") -)] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn minnumf64(_x: f64, _y: f64) -> f64 { @@ -4309,7 +4617,6 @@ pub const fn minnumf64(_x: f64, _y: f64) -> f64 { /// The stabilized version of this intrinsic is /// [`f128::min`] #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f128", issue = "116909"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn minnumf128(_x: f128, _y: f128) -> f128 { @@ -4326,7 +4633,6 @@ pub const fn minnumf128(_x: f128, _y: f128) -> f128 { /// The stabilized version of this intrinsic is /// [`f16::max`] #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f16", issue = "116909"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn maxnumf16(_x: f16, _y: f16) -> f16 { @@ -4343,11 +4649,7 @@ pub const fn maxnumf16(_x: f16, _y: f16) -> f16 { /// The stabilized version of this intrinsic is /// [`f32::max`] #[rustc_nounwind] -#[cfg_attr( - bootstrap, - rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION") -)] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn maxnumf32(_x: f32, _y: f32) -> f32 { @@ -4364,11 +4666,7 @@ pub const fn maxnumf32(_x: f32, _y: f32) -> f32 { /// The stabilized version of this intrinsic is /// [`f64::max`] #[rustc_nounwind] -#[cfg_attr( - bootstrap, - rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION") -)] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn maxnumf64(_x: f64, _y: f64) -> f64 { @@ -4385,7 +4683,6 @@ pub const fn maxnumf64(_x: f64, _y: f64) -> f64 { /// The stabilized version of this intrinsic is /// [`f128::max`] #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f128", issue = "116909"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn maxnumf128(_x: f128, _y: f128) -> f128 { @@ -4397,7 +4694,6 @@ pub const fn maxnumf128(_x: f128, _y: f128) -> f128 { /// The stabilized version of this intrinsic is /// [`f16::abs`](../../std/primitive.f16.html#method.abs) #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f16", issue = "116909"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn fabsf16(_x: f16) -> f16 { @@ -4409,11 +4705,7 @@ pub const unsafe fn fabsf16(_x: f16) -> f16 { /// The stabilized version of this intrinsic is /// [`f32::abs`](../../std/primitive.f32.html#method.abs) #[rustc_nounwind] -#[cfg_attr( - bootstrap, - rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION") -)] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn fabsf32(_x: f32) -> f32 { @@ -4425,11 +4717,7 @@ pub const unsafe fn fabsf32(_x: f32) -> f32 { /// The stabilized version of this intrinsic is /// [`f64::abs`](../../std/primitive.f64.html#method.abs) #[rustc_nounwind] -#[cfg_attr( - bootstrap, - rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION") -)] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn fabsf64(_x: f64) -> f64 { @@ -4441,7 +4729,6 @@ pub const unsafe fn fabsf64(_x: f64) -> f64 { /// The stabilized version of this intrinsic is /// [`f128::abs`](../../std/primitive.f128.html#method.abs) #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f128", issue = "116909"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn fabsf128(_x: f128) -> f128 { @@ -4453,7 +4740,6 @@ pub const unsafe fn fabsf128(_x: f128) -> f128 { /// The stabilized version of this intrinsic is /// [`f16::copysign`](../../std/primitive.f16.html#method.copysign) #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f16", issue = "116909"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn copysignf16(_x: f16, _y: f16) -> f16 { @@ -4465,11 +4751,7 @@ pub const unsafe fn copysignf16(_x: f16, _y: f16) -> f16 { /// The stabilized version of this intrinsic is /// [`f32::copysign`](../../std/primitive.f32.html#method.copysign) #[rustc_nounwind] -#[cfg_attr( - bootstrap, - rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION") -)] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn copysignf32(_x: f32, _y: f32) -> f32 { @@ -4480,11 +4762,7 @@ pub const unsafe fn copysignf32(_x: f32, _y: f32) -> f32 { /// The stabilized version of this intrinsic is /// [`f64::copysign`](../../std/primitive.f64.html#method.copysign) #[rustc_nounwind] -#[cfg_attr( - bootstrap, - rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION") -)] -#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] +#[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn copysignf64(_x: f64, _y: f64) -> f64 { @@ -4496,7 +4774,6 @@ pub const unsafe fn copysignf64(_x: f64, _y: f64) -> f64 { /// The stabilized version of this intrinsic is /// [`f128::copysign`](../../std/primitive.f128.html#method.copysign) #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "f128", issue = "116909"))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const unsafe fn copysignf128(_x: f128, _y: f128) -> f128 { diff --git a/core/src/intrinsics/simd.rs b/core/src/intrinsics/simd.rs index 5ddca9c4dce88..d03d801b93652 100644 --- a/core/src/intrinsics/simd.rs +++ b/core/src/intrinsics/simd.rs @@ -612,6 +612,20 @@ extern "rust-intrinsic" { #[rustc_nounwind] pub fn simd_fma(x: T, y: T, z: T) -> T; + /// Computes `(x*y) + z` for each element, non-deterministically executing either + /// a fused multiply-add or two operations with rounding of the intermediate result. + /// + /// The operation is fused if the code generator determines that target instruction + /// set has support for a fused operation, and that the fused operation is more efficient + /// than the equivalent, separate pair of mul and add instructions. It is unspecified + /// whether or not a fused operation is selected, and that may depend on optimization + /// level and context, for example. It may even be the case that some SIMD lanes get fused + /// and others do not. + /// + /// `T` must be a vector of floats. + #[rustc_nounwind] + pub fn simd_relaxed_fma(x: T, y: T, z: T) -> T; + // Computes the sine of each element. /// /// `T` must be a vector of floats. diff --git a/core/src/io/borrowed_buf.rs b/core/src/io/borrowed_buf.rs index 4227e503ba7ba..f86abf7f1e91c 100644 --- a/core/src/io/borrowed_buf.rs +++ b/core/src/io/borrowed_buf.rs @@ -94,7 +94,7 @@ impl<'data> BorrowedBuf<'data> { // SAFETY: We only slice the filled part of the buffer, which is always valid unsafe { let buf = self.buf.get_unchecked(..self.filled); - MaybeUninit::slice_assume_init_ref(buf) + buf.assume_init_ref() } } @@ -104,7 +104,7 @@ impl<'data> BorrowedBuf<'data> { // SAFETY: We only slice the filled part of the buffer, which is always valid unsafe { let buf = self.buf.get_unchecked_mut(..self.filled); - MaybeUninit::slice_assume_init_mut(buf) + buf.assume_init_mut() } } @@ -114,7 +114,7 @@ impl<'data> BorrowedBuf<'data> { // SAFETY: We only slice the filled part of the buffer, which is always valid unsafe { let buf = self.buf.get_unchecked(..self.filled); - MaybeUninit::slice_assume_init_ref(buf) + buf.assume_init_ref() } } @@ -124,7 +124,7 @@ impl<'data> BorrowedBuf<'data> { // SAFETY: We only slice the filled part of the buffer, which is always valid unsafe { let buf = self.buf.get_unchecked_mut(..self.filled); - MaybeUninit::slice_assume_init_mut(buf) + buf.assume_init_mut() } } @@ -233,7 +233,7 @@ impl<'a> BorrowedCursor<'a> { // SAFETY: We only slice the initialized part of the buffer, which is always valid unsafe { let buf = self.buf.buf.get_unchecked(self.buf.filled..self.buf.init); - MaybeUninit::slice_assume_init_ref(buf) + buf.assume_init_ref() } } @@ -243,7 +243,7 @@ impl<'a> BorrowedCursor<'a> { // SAFETY: We only slice the initialized part of the buffer, which is always valid unsafe { let buf = self.buf.buf.get_unchecked_mut(self.buf.filled..self.buf.init); - MaybeUninit::slice_assume_init_mut(buf) + buf.assume_init_mut() } } @@ -344,7 +344,7 @@ impl<'a> BorrowedCursor<'a> { // SAFETY: we do not de-initialize any of the elements of the slice unsafe { - MaybeUninit::copy_from_slice(&mut self.as_mut()[..buf.len()], buf); + self.as_mut()[..buf.len()].write_copy_of_slice(buf); } // SAFETY: We just added the entire contents of buf to the filled section. diff --git a/core/src/iter/adapters/filter_map.rs b/core/src/iter/adapters/filter_map.rs index cc64ceb13f766..24ec6b1741ce1 100644 --- a/core/src/iter/adapters/filter_map.rs +++ b/core/src/iter/adapters/filter_map.rs @@ -81,9 +81,7 @@ where if const { crate::mem::needs_drop::() } { // SAFETY: self.initialized is always <= N, which also is the length of the array. unsafe { - core::ptr::drop_in_place(MaybeUninit::slice_assume_init_mut( - self.array.get_unchecked_mut(..self.initialized), - )); + self.array.get_unchecked_mut(..self.initialized).assume_init_drop(); } } } diff --git a/core/src/iter/adapters/flatten.rs b/core/src/iter/adapters/flatten.rs index 0023b46031f12..9b9353b800a98 100644 --- a/core/src/iter/adapters/flatten.rs +++ b/core/src/iter/adapters/flatten.rs @@ -1,7 +1,7 @@ use crate::iter::adapters::SourceIter; use crate::iter::{ - Cloned, Copied, Empty, Filter, FilterMap, Fuse, FusedIterator, InPlaceIterable, Map, Once, - OnceWith, TrustedFused, TrustedLen, + Cloned, Copied, Empty, Filter, FilterMap, Fuse, FusedIterator, Map, Once, OnceWith, + TrustedFused, TrustedLen, }; use crate::num::NonZero; use crate::ops::{ControlFlow, Try}; @@ -157,21 +157,6 @@ where { } -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl InPlaceIterable for FlatMap -where - I: InPlaceIterable, - U: BoundedSize + IntoIterator, -{ - const EXPAND_BY: Option> = const { - match (I::EXPAND_BY, U::UPPER_BOUND) { - (Some(m), Some(n)) => m.checked_mul(n), - _ => None, - } - }; - const MERGE_BY: Option> = I::MERGE_BY; -} - #[unstable(issue = "none", feature = "inplace_iteration")] unsafe impl SourceIter for FlatMap where @@ -386,21 +371,6 @@ where { } -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl InPlaceIterable for Flatten -where - I: InPlaceIterable + Iterator, - ::Item: IntoIterator + BoundedSize, -{ - const EXPAND_BY: Option> = const { - match (I::EXPAND_BY, I::Item::UPPER_BOUND) { - (Some(m), Some(n)) => m.checked_mul(n), - _ => None, - } - }; - const MERGE_BY: Option> = I::MERGE_BY; -} - #[unstable(issue = "none", feature = "inplace_iteration")] unsafe impl SourceIter for Flatten where diff --git a/core/src/iter/sources/from_fn.rs b/core/src/iter/sources/from_fn.rs index 3cd3830471cfe..5f3d404d7dca2 100644 --- a/core/src/iter/sources/from_fn.rs +++ b/core/src/iter/sources/from_fn.rs @@ -3,6 +3,8 @@ use crate::fmt; /// Creates a new iterator where each iteration calls the provided closure /// `F: FnMut() -> Option`. /// +/// The iterator will yield the `T`s returned from the closure. +/// /// This allows creating a custom iterator with any behavior /// without using the more verbose syntax of creating a dedicated type /// and implementing the [`Iterator`] trait for it. diff --git a/core/src/iter/sources/once.rs b/core/src/iter/sources/once.rs index 21be4377da1ca..c4a9860bdd76c 100644 --- a/core/src/iter/sources/once.rs +++ b/core/src/iter/sources/once.rs @@ -34,7 +34,7 @@ use crate::iter::{FusedIterator, TrustedLen}; /// use std::fs; /// use std::path::PathBuf; /// -/// let dirs = fs::read_dir(".foo").unwrap(); +/// let dirs = fs::read_dir(".foo")?; /// /// // we need to convert from an iterator of DirEntry-s to an iterator of /// // PathBufs, so we use map @@ -50,6 +50,7 @@ use crate::iter::{FusedIterator, TrustedLen}; /// for f in files { /// println!("{f:?}"); /// } +/// # std::io::Result::Ok(()) /// ``` #[stable(feature = "iter_once", since = "1.2.0")] pub fn once(value: T) -> Once { diff --git a/core/src/iter/sources/successors.rs b/core/src/iter/sources/successors.rs index 36bc4035039e6..e14c9235e5562 100644 --- a/core/src/iter/sources/successors.rs +++ b/core/src/iter/sources/successors.rs @@ -5,6 +5,7 @@ use crate::iter::FusedIterator; /// /// The iterator starts with the given first item (if any) /// and calls the given `FnMut(&T) -> Option` closure to compute each item’s successor. +/// The iterator will yield the `T`s returned from the closure. /// /// ``` /// use std::iter::successors; diff --git a/core/src/iter/traits/collect.rs b/core/src/iter/traits/collect.rs index 2cf2ea58fd4ee..97bb21c8a36e8 100644 --- a/core/src/iter/traits/collect.rs +++ b/core/src/iter/traits/collect.rs @@ -152,39 +152,6 @@ pub trait FromIterator: Sized { fn from_iter>(iter: T) -> Self; } -/// This implementation turns an iterator of tuples into a tuple of types which implement -/// [`Default`] and [`Extend`]. -/// -/// This is similar to [`Iterator::unzip`], but is also composable with other [`FromIterator`] -/// implementations: -/// -/// ```rust -/// # fn main() -> Result<(), core::num::ParseIntError> { -/// let string = "1,2,123,4"; -/// -/// let (numbers, lengths): (Vec<_>, Vec<_>) = string -/// .split(',') -/// .map(|s| s.parse().map(|n: u32| (n, s.len()))) -/// .collect::>()?; -/// -/// assert_eq!(numbers, [1, 2, 123, 4]); -/// assert_eq!(lengths, [1, 1, 3, 1]); -/// # Ok(()) } -/// ``` -#[stable(feature = "from_iterator_for_tuple", since = "1.79.0")] -impl FromIterator<(AE, BE)> for (A, B) -where - A: Default + Extend, - B: Default + Extend, -{ - fn from_iter>(iter: I) -> Self { - let mut res = <(A, B)>::default(); - res.extend(iter); - - res - } -} - /// Conversion into an [`Iterator`]. /// /// By implementing `IntoIterator` for a type, you define how it will be @@ -492,131 +459,234 @@ impl Extend<()> for () { fn extend_one(&mut self, _item: ()) {} } -#[stable(feature = "extend_for_tuple", since = "1.56.0")] -impl Extend<(A, B)> for (ExtendA, ExtendB) -where - ExtendA: Extend, - ExtendB: Extend, -{ - /// Allows to `extend` a tuple of collections that also implement `Extend`. - /// - /// See also: [`Iterator::unzip`] - /// - /// # Examples - /// ``` - /// let mut tuple = (vec![0], vec![1]); - /// tuple.extend([(2, 3), (4, 5), (6, 7)]); - /// assert_eq!(tuple.0, [0, 2, 4, 6]); - /// assert_eq!(tuple.1, [1, 3, 5, 7]); - /// - /// // also allows for arbitrarily nested tuples as elements - /// let mut nested_tuple = (vec![1], (vec![2], vec![3])); - /// nested_tuple.extend([(4, (5, 6)), (7, (8, 9))]); - /// - /// let (a, (b, c)) = nested_tuple; - /// assert_eq!(a, [1, 4, 7]); - /// assert_eq!(b, [2, 5, 8]); - /// assert_eq!(c, [3, 6, 9]); - /// ``` - fn extend>(&mut self, into_iter: T) { - let (a, b) = self; - let iter = into_iter.into_iter(); - SpecTupleExtend::extend(iter, a, b); - } +macro_rules! spec_tuple_impl { + ( + ( + $ty_name:ident, $var_name:ident, $extend_ty_name: ident, + $trait_name:ident, $default_fn_name:ident, $cnt:tt + ), + ) => { + spec_tuple_impl!( + $trait_name, + $default_fn_name, + #[doc(fake_variadic)] + #[doc = "This trait is implemented for tuples up to twelve items long. The `impl`s for \ + 1- and 3- through 12-ary tuples were stabilized after 2-tuples, in \ + 1.85.0."] + => ($ty_name, $var_name, $extend_ty_name, $cnt), + ); + }; + ( + ( + $ty_name:ident, $var_name:ident, $extend_ty_name: ident, + $trait_name:ident, $default_fn_name:ident, $cnt:tt + ), + $( + ( + $ty_names:ident, $var_names:ident, $extend_ty_names:ident, + $trait_names:ident, $default_fn_names:ident, $cnts:tt + ), + )* + ) => { + spec_tuple_impl!( + $( + ( + $ty_names, $var_names, $extend_ty_names, + $trait_names, $default_fn_names, $cnts + ), + )* + ); + spec_tuple_impl!( + $trait_name, + $default_fn_name, + #[doc(hidden)] + => ( + $ty_name, $var_name, $extend_ty_name, $cnt + ), + $( + ( + $ty_names, $var_names, $extend_ty_names, $cnts + ), + )* + ); + }; + ( + $trait_name:ident, $default_fn_name:ident, #[$meta:meta] + $(#[$doctext:meta])? => $( + ( + $ty_names:ident, $var_names:ident, $extend_ty_names:ident, $cnts:tt + ), + )* + ) => { + #[$meta] + $(#[$doctext])? + #[stable(feature = "extend_for_tuple", since = "1.56.0")] + impl<$($ty_names,)* $($extend_ty_names,)*> Extend<($($ty_names,)*)> for ($($extend_ty_names,)*) + where + $($extend_ty_names: Extend<$ty_names>,)* + { + /// Allows to `extend` a tuple of collections that also implement `Extend`. + /// + /// See also: [`Iterator::unzip`] + /// + /// # Examples + /// ``` + /// // Example given for a 2-tuple, but 1- through 12-tuples are supported + /// let mut tuple = (vec![0], vec![1]); + /// tuple.extend([(2, 3), (4, 5), (6, 7)]); + /// assert_eq!(tuple.0, [0, 2, 4, 6]); + /// assert_eq!(tuple.1, [1, 3, 5, 7]); + /// + /// // also allows for arbitrarily nested tuples as elements + /// let mut nested_tuple = (vec![1], (vec![2], vec![3])); + /// nested_tuple.extend([(4, (5, 6)), (7, (8, 9))]); + /// + /// let (a, (b, c)) = nested_tuple; + /// assert_eq!(a, [1, 4, 7]); + /// assert_eq!(b, [2, 5, 8]); + /// assert_eq!(c, [3, 6, 9]); + /// ``` + fn extend>(&mut self, into_iter: T) { + let ($($var_names,)*) = self; + let iter = into_iter.into_iter(); + $trait_name::extend(iter, $($var_names,)*); + } - fn extend_one(&mut self, item: (A, B)) { - self.0.extend_one(item.0); - self.1.extend_one(item.1); - } + fn extend_one(&mut self, item: ($($ty_names,)*)) { + $(self.$cnts.extend_one(item.$cnts);)* + } - fn extend_reserve(&mut self, additional: usize) { - self.0.extend_reserve(additional); - self.1.extend_reserve(additional); - } + fn extend_reserve(&mut self, additional: usize) { + $(self.$cnts.extend_reserve(additional);)* + } - unsafe fn extend_one_unchecked(&mut self, item: (A, B)) { - // SAFETY: Those are our safety preconditions, and we correctly forward `extend_reserve`. - unsafe { - self.0.extend_one_unchecked(item.0); - self.1.extend_one_unchecked(item.1); + unsafe fn extend_one_unchecked(&mut self, item: ($($ty_names,)*)) { + // SAFETY: Those are our safety preconditions, and we correctly forward `extend_reserve`. + unsafe { + $(self.$cnts.extend_one_unchecked(item.$cnts);)* + } + } } - } -} -fn default_extend_tuple( - iter: impl Iterator, - a: &mut ExtendA, - b: &mut ExtendB, -) where - ExtendA: Extend, - ExtendB: Extend, -{ - fn extend<'a, A, B>( - a: &'a mut impl Extend, - b: &'a mut impl Extend, - ) -> impl FnMut((), (A, B)) + 'a { - move |(), (t, u)| { - a.extend_one(t); - b.extend_one(u); + trait $trait_name<$($ty_names),*> { + fn extend(self, $($var_names: &mut $ty_names,)*); } - } - let (lower_bound, _) = iter.size_hint(); - if lower_bound > 0 { - a.extend_reserve(lower_bound); - b.extend_reserve(lower_bound); - } - - iter.fold((), extend(a, b)); -} + fn $default_fn_name<$($ty_names,)* $($extend_ty_names,)*>( + iter: impl Iterator, + $($var_names: &mut $extend_ty_names,)* + ) where + $($extend_ty_names: Extend<$ty_names>,)* + { + fn extend<'a, $($ty_names,)*>( + $($var_names: &'a mut impl Extend<$ty_names>,)* + ) -> impl FnMut((), ($($ty_names,)*)) + 'a { + #[allow(non_snake_case)] + move |(), ($($extend_ty_names,)*)| { + $($var_names.extend_one($extend_ty_names);)* + } + } -trait SpecTupleExtend { - fn extend(self, a: &mut A, b: &mut B); -} + let (lower_bound, _) = iter.size_hint(); + if lower_bound > 0 { + $($var_names.extend_reserve(lower_bound);)* + } -impl SpecTupleExtend for Iter -where - ExtendA: Extend, - ExtendB: Extend, - Iter: Iterator, -{ - default fn extend(self, a: &mut ExtendA, b: &mut ExtendB) { - default_extend_tuple(self, a, b); - } -} + iter.fold((), extend($($var_names,)*)); + } -impl SpecTupleExtend for Iter -where - ExtendA: Extend, - ExtendB: Extend, - Iter: TrustedLen, -{ - fn extend(self, a: &mut ExtendA, b: &mut ExtendB) { - fn extend<'a, A, B>( - a: &'a mut impl Extend, - b: &'a mut impl Extend, - ) -> impl FnMut((), (A, B)) + 'a { - // SAFETY: We reserve enough space for the `size_hint`, and the iterator is `TrustedLen` - // so its `size_hint` is exact. - move |(), (t, u)| unsafe { - a.extend_one_unchecked(t); - b.extend_one_unchecked(u); + impl<$($ty_names,)* $($extend_ty_names,)* Iter> $trait_name<$($extend_ty_names),*> for Iter + where + $($extend_ty_names: Extend<$ty_names>,)* + Iter: Iterator, + { + default fn extend(self, $($var_names: &mut $extend_ty_names),*) { + $default_fn_name(self, $($var_names),*); } } - let (lower_bound, upper_bound) = self.size_hint(); + impl<$($ty_names,)* $($extend_ty_names,)* Iter> $trait_name<$($extend_ty_names),*> for Iter + where + $($extend_ty_names: Extend<$ty_names>,)* + Iter: TrustedLen, + { + fn extend(self, $($var_names: &mut $extend_ty_names,)*) { + fn extend<'a, $($ty_names,)*>( + $($var_names: &'a mut impl Extend<$ty_names>,)* + ) -> impl FnMut((), ($($ty_names,)*)) + 'a { + #[allow(non_snake_case)] + // SAFETY: We reserve enough space for the `size_hint`, and the iterator is + // `TrustedLen` so its `size_hint` is exact. + move |(), ($($extend_ty_names,)*)| unsafe { + $($var_names.extend_one_unchecked($extend_ty_names);)* + } + } + + let (lower_bound, upper_bound) = self.size_hint(); + + if upper_bound.is_none() { + // We cannot reserve more than `usize::MAX` items, and this is likely to go out of memory anyway. + $default_fn_name(self, $($var_names,)*); + return; + } + + if lower_bound > 0 { + $($var_names.extend_reserve(lower_bound);)* + } - if upper_bound.is_none() { - // We cannot reserve more than `usize::MAX` items, and this is likely to go out of memory anyway. - default_extend_tuple(self, a, b); - return; + self.fold((), extend($($var_names,)*)); + } } - if lower_bound > 0 { - a.extend_reserve(lower_bound); - b.extend_reserve(lower_bound); + /// This implementation turns an iterator of tuples into a tuple of types which implement + /// [`Default`] and [`Extend`]. + /// + /// This is similar to [`Iterator::unzip`], but is also composable with other [`FromIterator`] + /// implementations: + /// + /// ```rust + /// # fn main() -> Result<(), core::num::ParseIntError> { + /// let string = "1,2,123,4"; + /// + /// // Example given for a 2-tuple, but 1- through 12-tuples are supported + /// let (numbers, lengths): (Vec<_>, Vec<_>) = string + /// .split(',') + /// .map(|s| s.parse().map(|n: u32| (n, s.len()))) + /// .collect::>()?; + /// + /// assert_eq!(numbers, [1, 2, 123, 4]); + /// assert_eq!(lengths, [1, 1, 3, 1]); + /// # Ok(()) } + /// ``` + #[$meta] + $(#[$doctext])? + #[stable(feature = "from_iterator_for_tuple", since = "1.79.0")] + impl<$($ty_names,)* $($extend_ty_names,)*> FromIterator<($($extend_ty_names,)*)> for ($($ty_names,)*) + where + $($ty_names: Default + Extend<$extend_ty_names>,)* + { + fn from_iter>(iter: Iter) -> Self { + let mut res = <($($ty_names,)*)>::default(); + res.extend(iter); + + res + } } - self.fold((), extend(a, b)); - } + }; } + +spec_tuple_impl!( + (L, l, EL, TraitL, default_extend_tuple_l, 11), + (K, k, EK, TraitK, default_extend_tuple_k, 10), + (J, j, EJ, TraitJ, default_extend_tuple_j, 9), + (I, i, EI, TraitI, default_extend_tuple_i, 8), + (H, h, EH, TraitH, default_extend_tuple_h, 7), + (G, g, EG, TraitG, default_extend_tuple_g, 6), + (F, f, EF, TraitF, default_extend_tuple_f, 5), + (E, e, EE, TraitE, default_extend_tuple_e, 4), + (D, d, ED, TraitD, default_extend_tuple_d, 3), + (C, c, EC, TraitC, default_extend_tuple_c, 2), + (B, b, EB, TraitB, default_extend_tuple_b, 1), + (A, a, EA, TraitA, default_extend_tuple_a, 0), +); diff --git a/core/src/iter/traits/iterator.rs b/core/src/iter/traits/iterator.rs index ffaf1bc56e942..91c3a4b29b539 100644 --- a/core/src/iter/traits/iterator.rs +++ b/core/src/iter/traits/iterator.rs @@ -1553,7 +1553,7 @@ pub trait Iterator { /// /// # Panics /// - /// Panics if `N` is 0. This check will most probably get changed to a + /// Panics if `N` is zero. This check will most probably get changed to a /// compile time error before this method gets stabilized. /// /// ```should_panic @@ -2564,7 +2564,7 @@ pub trait Iterator { /// # Example /// /// ``` - /// let reduced: i32 = (1..10).reduce(|acc, e| acc + e).unwrap(); + /// let reduced: i32 = (1..10).reduce(|acc, e| acc + e).unwrap_or(0); /// assert_eq!(reduced, 45); /// /// // Which is equivalent to doing it with `fold`: @@ -3051,6 +3051,7 @@ pub trait Iterator { /// /// // we can still use `iter`, as there are more elements. /// assert_eq!(iter.next(), Some(&-1)); + /// assert_eq!(iter.next_back(), Some(&3)); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -3087,7 +3088,7 @@ pub trait Iterator { /// [2.4, f32::NAN, 1.3] /// .into_iter() /// .reduce(f32::max) - /// .unwrap(), + /// .unwrap_or(0.), /// 2.4 /// ); /// ``` @@ -3123,7 +3124,7 @@ pub trait Iterator { /// [2.4, f32::NAN, 1.3] /// .into_iter() /// .reduce(f32::min) - /// .unwrap(), + /// .unwrap_or(0.), /// 1.3 /// ); /// ``` @@ -3454,7 +3455,7 @@ pub trait Iterator { /// /// # Panics /// - /// Panics if `N` is 0. + /// Panics if `N` is zero. /// /// # Examples /// diff --git a/core/src/lib.rs b/core/src/lib.rs index a178d10125477..e845bb34426c4 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -107,32 +107,13 @@ // // Library features: // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(const_exact_div))] -#![cfg_attr(bootstrap, feature(const_fmt_arguments_new))] -#![cfg_attr(bootstrap, feature(const_ub_checks))] #![feature(array_ptr_get)] #![feature(asm_experimental_arch)] -#![feature(const_align_of_val)] -#![feature(const_align_of_val_raw)] -#![feature(const_alloc_layout)] -#![feature(const_black_box)] -#![feature(const_eq_ignore_ascii_case)] +#![feature(bigint_helper_methods)] +#![feature(const_carrying_mul_add)] #![feature(const_eval_select)] -#![feature(const_heap)] -#![feature(const_nonnull_new)] -#![feature(const_ptr_sub_ptr)] -#![feature(const_raw_ptr_comparison)] -#![feature(const_size_of_val)] -#![feature(const_size_of_val_raw)] -#![feature(const_sockaddr_setters)] -#![feature(const_swap)] -#![feature(const_try)] -#![feature(const_type_id)] -#![feature(const_type_name)] -#![feature(const_typed_swap)] #![feature(core_intrinsics)] #![feature(coverage_attribute)] -#![feature(do_not_recommend)] #![feature(internal_impls_macro)] #![feature(ip)] #![feature(is_ascii_octdigit)] @@ -144,6 +125,7 @@ #![feature(ptr_alignment_type)] #![feature(ptr_metadata)] #![feature(set_ptr_value)] +#![feature(slice_as_array)] #![feature(slice_as_chunks)] #![feature(slice_ptr_get)] #![feature(str_internals)] @@ -158,8 +140,6 @@ // // Language features: // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(strict_provenance))] -#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))] #![feature(abi_unadjusted)] #![feature(adt_const_params)] #![feature(allow_internal_unsafe)] @@ -169,10 +149,7 @@ #![feature(cfg_target_has_atomic)] #![feature(cfg_target_has_atomic_equal_alignment)] #![feature(cfg_ub_checks)] -#![feature(const_for)] -#![feature(const_is_char_boundary)] #![feature(const_precise_live_drops)] -#![feature(const_str_split_at)] #![feature(const_trait_impl)] #![feature(decl_macro)] #![feature(deprecated_suggestion)] @@ -209,6 +186,7 @@ #![feature(simd_ffi)] #![feature(staged_api)] #![feature(stmt_expr_attributes)] +#![feature(strict_provenance_lints)] #![feature(target_feature_11)] #![feature(trait_alias)] #![feature(transparent_unions)] @@ -258,7 +236,6 @@ pub mod assert_matches { } // We don't export this through #[macro_export] for now, to avoid breakage. -#[cfg(not(bootstrap))] #[unstable(feature = "autodiff", issue = "124509")] /// Unstable module containing the unstable `autodiff` macro. pub mod autodiff { @@ -368,7 +345,7 @@ pub mod net; pub mod option; pub mod panic; pub mod panicking; -#[unstable(feature = "core_pattern_types", issue = "123646")] +#[unstable(feature = "pattern_type_macro", issue = "123646")] pub mod pat; pub mod pin; #[unstable(feature = "random", issue = "130703")] @@ -377,6 +354,8 @@ pub mod random; pub mod range; pub mod result; pub mod sync; +#[unstable(feature = "unsafe_binders", issue = "130516")] +pub mod unsafe_binder; pub mod fmt; pub mod hash; diff --git a/core/src/macros/mod.rs b/core/src/macros/mod.rs index 771c2d31b60e0..402b436d28e68 100644 --- a/core/src/macros/mod.rs +++ b/core/src/macros/mod.rs @@ -1549,12 +1549,11 @@ pub(crate) mod builtin { /// NAME is a string that represents a valid function name. /// MODE is any of Forward, Reverse, ForwardFirst, ReverseFirst. /// INPUT_ACTIVITIES consists of one valid activity for each input parameter. - /// OUTPUT_ACTIVITY must not be set if we implicitely return nothing (or explicitely return + /// OUTPUT_ACTIVITY must not be set if we implicitly return nothing (or explicitly return /// `-> ()`). Otherwise it must be set to one of the allowed activities. #[unstable(feature = "autodiff", issue = "124509")] #[allow_internal_unstable(rustc_attrs)] #[rustc_builtin_macro] - #[cfg(not(bootstrap))] pub macro autodiff($item:item) { /* compiler built-in */ } diff --git a/core/src/marker.rs b/core/src/marker.rs index acbad07746bb9..01af964a83e26 100644 --- a/core/src/marker.rs +++ b/core/src/marker.rs @@ -141,7 +141,8 @@ unsafe impl Send for &T {} )] #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable #[rustc_specialization_trait] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[rustc_deny_explicit_impl] +#[rustc_do_not_implement_via_object] #[rustc_coinductive] pub trait Sized { // Empty. @@ -181,31 +182,27 @@ pub trait Sized { /// [^1]: Formerly known as *object safe*. #[unstable(feature = "unsize", issue = "18598")] #[lang = "unsize"] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[rustc_deny_explicit_impl] +#[rustc_do_not_implement_via_object] pub trait Unsize { // Empty. } /// Required trait for constants used in pattern matches. /// -/// Any type that derives `PartialEq` automatically implements this trait, -/// *regardless* of whether its type-parameters implement `PartialEq`. +/// Constants are only allowed as patterns if (a) their type implements +/// `PartialEq`, and (b) interpreting the value of the constant as a pattern +/// is equialent to calling `PartialEq`. This ensures that constants used as +/// patterns cannot expose implementation details in an unexpected way or +/// cause semver hazards. /// -/// If a `const` item contains some type that does not implement this trait, -/// then that type either (1.) does not implement `PartialEq` (which means the -/// constant will not provide that comparison method, which code generation -/// assumes is available), or (2.) it implements *its own* version of -/// `PartialEq` (which we assume does not conform to a structural-equality -/// comparison). +/// This trait ensures point (b). +/// Any type that derives `PartialEq` automatically implements this trait. /// -/// In either of the two scenarios above, we reject usage of such a constant in -/// a pattern match. -/// -/// See also the [structural match RFC][RFC1445], and [issue 63438] which -/// motivated migrating from an attribute-based design to this trait. -/// -/// [RFC1445]: https://github.com/rust-lang/rfcs/blob/master/text/1445-restrict-constants-in-patterns.md -/// [issue 63438]: https://github.com/rust-lang/rust/issues/63438 +/// Implementing this trait (which is unstable) is a way for type authors to explicitly allow +/// comparing const values of this type; that operation will recursively compare all fields +/// (including private fields), even if that behavior differs from `PartialEq`. This can make it +/// semver-breaking to add further private fields to a type. #[unstable(feature = "structural_match", issue = "31434")] #[diagnostic::on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")] #[lang = "structural_peq"] @@ -815,7 +812,8 @@ impl StructuralPartialEq for PhantomData {} reason = "this trait is unlikely to ever be stabilized, use `mem::discriminant` instead" )] #[lang = "discriminant_kind"] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[rustc_deny_explicit_impl] +#[rustc_do_not_implement_via_object] pub trait DiscriminantKind { /// The type of the discriminant, which must satisfy the trait /// bounds required by `mem::Discriminant`. @@ -954,9 +952,12 @@ marker_impls! { /// This should be used for `~const` bounds, /// as non-const bounds will always hold for every type. #[unstable(feature = "const_destruct", issue = "133214")] +#[rustc_const_unstable(feature = "const_destruct", issue = "133214")] #[lang = "destruct"] #[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[rustc_deny_explicit_impl] +#[rustc_do_not_implement_via_object] +#[const_trait] pub trait Destruct {} /// A marker for tuple types. @@ -966,25 +967,33 @@ pub trait Destruct {} #[unstable(feature = "tuple_trait", issue = "none")] #[lang = "tuple_trait"] #[diagnostic::on_unimplemented(message = "`{Self}` is not a tuple")] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[rustc_deny_explicit_impl] +#[rustc_do_not_implement_via_object] pub trait Tuple {} /// A marker for pointer-like types. /// -/// All types that have the same size and alignment as a `usize` or -/// `*const ()` automatically implement this trait. +/// This trait can only be implemented for types that are certain to have +/// the same size and alignment as a [`usize`] or [`*const ()`](pointer). +/// To ensure this, there are special requirements on implementations +/// of `PointerLike` (other than the already-provided implementations +/// for built-in types): +/// +/// * The type must have `#[repr(transparent)]`. +/// * The type’s sole non-zero-sized field must itself implement `PointerLike`. #[unstable(feature = "pointer_like_trait", issue = "none")] #[lang = "pointer_like"] #[diagnostic::on_unimplemented( message = "`{Self}` needs to have the same ABI as a pointer", label = "`{Self}` needs to be a pointer-like type" )] +#[rustc_do_not_implement_via_object] pub trait PointerLike {} -#[cfg(not(bootstrap))] marker_impls! { #[unstable(feature = "pointer_like_trait", issue = "none")] PointerLike for + isize, usize, {T} &T, {T} &mut T, @@ -1067,7 +1076,8 @@ marker_impls! { reason = "internal trait for implementing various traits for all function pointers" )] #[lang = "fn_ptr_trait"] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[rustc_deny_explicit_impl] +#[rustc_do_not_implement_via_object] pub trait FnPtr: Copy + Clone { /// Returns the address of the function pointer. #[lang = "fn_ptr_addr"] @@ -1078,7 +1088,6 @@ pub trait FnPtr: Copy + Clone { #[rustc_builtin_macro(CoercePointee, attributes(pointee))] #[allow_internal_unstable(dispatch_from_dyn, coerce_unsized, unsize)] #[unstable(feature = "derive_coerce_pointee", issue = "123430")] -#[cfg(not(bootstrap))] pub macro CoercePointee($item:item) { /* compiler built-in */ } diff --git a/core/src/mem/maybe_uninit.rs b/core/src/mem/maybe_uninit.rs index 58315cb74f0a1..ac5307a671d20 100644 --- a/core/src/mem/maybe_uninit.rs +++ b/core/src/mem/maybe_uninit.rs @@ -1,5 +1,5 @@ use crate::any::type_name; -use crate::mem::{self, ManuallyDrop}; +use crate::mem::ManuallyDrop; use crate::{fmt, intrinsics, ptr, slice}; /// A wrapper type to construct uninitialized instances of `T`. @@ -232,6 +232,26 @@ use crate::{fmt, intrinsics, ptr, slice}; /// remain `#[repr(transparent)]`. That said, `MaybeUninit` will *always* guarantee that it has /// the same size, alignment, and ABI as `T`; it's just that the way `MaybeUninit` implements that /// guarantee may evolve. +/// +/// Note that even though `T` and `MaybeUninit` are ABI compatible it is still unsound to +/// transmute `&mut T` to `&mut MaybeUninit` and expose that to safe code because it would allow +/// safe code to access uninitialized memory: +/// +/// ```rust,no_run +/// use core::mem::MaybeUninit; +/// +/// fn unsound_transmute(val: &mut T) -> &mut MaybeUninit { +/// unsafe { core::mem::transmute(val) } +/// } +/// +/// fn main() { +/// let mut code = 0; +/// let code = &mut code; +/// let code2 = unsound_transmute(code); +/// *code2 = MaybeUninit::uninit(); +/// std::process::exit(*code); // UB! Accessing uninitialized memory. +/// } +/// ``` #[stable(feature = "maybe_uninit", since = "1.36.0")] // Lang item so we can wrap other types in it. This is useful for coroutines. #[lang = "maybe_uninit"] @@ -255,7 +275,11 @@ impl Clone for MaybeUninit { #[stable(feature = "maybe_uninit_debug", since = "1.41.0")] impl fmt::Debug for MaybeUninit { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.pad(type_name::()) + // NB: there is no `.pad_fmt` so we can't use a simpler `format_args!("MaybeUninit<{..}>"). + // This needs to be adjusted if `MaybeUninit` moves modules. + let full_name = type_name::(); + let short_name = full_name.split_once("mem::maybe_uninit::").unwrap().1; + f.pad(short_name) } } @@ -330,7 +354,7 @@ impl MaybeUninit { /// fn read(buf: &mut [MaybeUninit]) -> &[u8] { /// unsafe { /// let len = read_into_buffer(buf.as_mut_ptr() as *mut u8, buf.len()); - /// MaybeUninit::slice_assume_init_ref(&buf[..len]) + /// buf[..len].assume_init_ref() /// } /// } /// @@ -481,9 +505,9 @@ impl MaybeUninit { /// } /// } /// ``` - #[stable(feature = "maybe_uninit_write", since = "1.55.0")] - #[rustc_const_unstable(feature = "const_maybe_uninit_write", issue = "63567")] #[inline(always)] + #[stable(feature = "maybe_uninit_write", since = "1.55.0")] + #[rustc_const_stable(feature = "const_maybe_uninit_write", since = "1.85.0")] pub const fn write(&mut self, val: T) -> &mut T { *self = MaybeUninit::new(val); // SAFETY: We just initialized this value. @@ -525,7 +549,7 @@ impl MaybeUninit { /// until they are, it is advisable to avoid them.) #[stable(feature = "maybe_uninit", since = "1.36.0")] #[rustc_const_stable(feature = "const_maybe_uninit_as_ptr", since = "1.59.0")] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[inline(always)] pub const fn as_ptr(&self) -> *const T { // `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer. @@ -567,7 +591,7 @@ impl MaybeUninit { /// until they are, it is advisable to avoid them.) #[stable(feature = "maybe_uninit", since = "1.36.0")] #[rustc_const_stable(feature = "const_maybe_uninit_as_mut_ptr", since = "1.83.0")] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[inline(always)] pub const fn as_mut_ptr(&mut self) -> *mut T { // `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer. @@ -716,7 +740,7 @@ impl MaybeUninit { /// /// On top of that, all additional invariants of the type `T` must be /// satisfied, as the `Drop` implementation of `T` (or its members) may - /// rely on this. For example, setting a [`Vec`] to an invalid but + /// rely on this. For example, setting a `Vec` to an invalid but /// non-null address makes it initialized (under the current implementation; /// this does not constitute a stable guarantee), because the only /// requirement the compiler knows about it is that the data pointer must be @@ -724,7 +748,6 @@ impl MaybeUninit { /// behavior. /// /// [`assume_init`]: MaybeUninit::assume_init - /// [`Vec`]: ../../std/vec/struct.Vec.html #[stable(feature = "maybe_uninit_extra", since = "1.60.0")] pub unsafe fn assume_init_drop(&mut self) { // SAFETY: the caller must guarantee that `self` is initialized and @@ -907,10 +930,7 @@ impl MaybeUninit { /// }; /// ``` #[stable(feature = "maybe_uninit_ref", since = "1.55.0")] - #[rustc_const_stable( - feature = "const_maybe_uninit_assume_init", - since = "CURRENT_RUSTC_VERSION" - )] + #[rustc_const_stable(feature = "const_maybe_uninit_assume_init", since = "1.84.0")] #[inline(always)] pub const unsafe fn assume_init_mut(&mut self) -> &mut T { // SAFETY: the caller must guarantee that `self` is initialized. @@ -961,44 +981,87 @@ impl MaybeUninit { } } - /// Assuming all the elements are initialized, get a slice to them. + /// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes. /// - /// # Safety + /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still + /// contain padding bytes which are left uninitialized. /// - /// It is up to the caller to guarantee that the `MaybeUninit` elements - /// really are in an initialized state. - /// Calling this when the content is not yet fully initialized causes undefined behavior. + /// # Examples /// - /// See [`assume_init_ref`] for more details and examples. + /// ``` + /// #![feature(maybe_uninit_as_bytes, maybe_uninit_slice)] + /// use std::mem::MaybeUninit; /// - /// [`assume_init_ref`]: MaybeUninit::assume_init_ref - #[unstable(feature = "maybe_uninit_slice", issue = "63569")] - #[inline(always)] - pub const unsafe fn slice_assume_init_ref(slice: &[Self]) -> &[T] { - // SAFETY: casting `slice` to a `*const [T]` is safe since the caller guarantees that - // `slice` is initialized, and `MaybeUninit` is guaranteed to have the same layout as `T`. - // The pointer obtained is valid since it refers to memory owned by `slice` which is a - // reference and thus guaranteed to be valid for reads. - unsafe { &*(slice as *const [Self] as *const [T]) } + /// let val = 0x12345678_i32; + /// let uninit = MaybeUninit::new(val); + /// let uninit_bytes = uninit.as_bytes(); + /// let bytes = unsafe { uninit_bytes.assume_init_ref() }; + /// assert_eq!(bytes, val.to_ne_bytes()); + /// ``` + #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")] + pub const fn as_bytes(&self) -> &[MaybeUninit] { + // SAFETY: MaybeUninit is always valid, even for padding bytes + unsafe { + slice::from_raw_parts(self.as_ptr().cast::>(), super::size_of::()) + } } - /// Assuming all the elements are initialized, get a mutable slice to them. + /// Returns the contents of this `MaybeUninit` as a mutable slice of potentially uninitialized + /// bytes. /// - /// # Safety + /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still + /// contain padding bytes which are left uninitialized. /// - /// It is up to the caller to guarantee that the `MaybeUninit` elements - /// really are in an initialized state. - /// Calling this when the content is not yet fully initialized causes undefined behavior. + /// # Examples /// - /// See [`assume_init_mut`] for more details and examples. + /// ``` + /// #![feature(maybe_uninit_as_bytes)] + /// use std::mem::MaybeUninit; /// - /// [`assume_init_mut`]: MaybeUninit::assume_init_mut + /// let val = 0x12345678_i32; + /// let mut uninit = MaybeUninit::new(val); + /// let uninit_bytes = uninit.as_bytes_mut(); + /// if cfg!(target_endian = "little") { + /// uninit_bytes[0].write(0xcd); + /// } else { + /// uninit_bytes[3].write(0xcd); + /// } + /// let val2 = unsafe { uninit.assume_init() }; + /// assert_eq!(val2, 0x123456cd); + /// ``` + #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")] + pub const fn as_bytes_mut(&mut self) -> &mut [MaybeUninit] { + // SAFETY: MaybeUninit is always valid, even for padding bytes + unsafe { + slice::from_raw_parts_mut( + self.as_mut_ptr().cast::>(), + super::size_of::(), + ) + } + } + + /// Deprecated version of [`slice::assume_init_ref`]. #[unstable(feature = "maybe_uninit_slice", issue = "63569")] - #[inline(always)] + #[rustc_const_unstable(feature = "maybe_uninit_slice", issue = "63569")] + #[deprecated( + note = "replaced by inherent assume_init_ref method; will eventually be removed", + since = "1.83.0" + )] + pub const unsafe fn slice_assume_init_ref(slice: &[Self]) -> &[T] { + // SAFETY: Same for both methods. + unsafe { slice.assume_init_ref() } + } + + /// Deprecated version of [`slice::assume_init_mut`]. + #[unstable(feature = "maybe_uninit_slice", issue = "63569")] + #[rustc_const_unstable(feature = "maybe_uninit_slice", issue = "63569")] + #[deprecated( + note = "replaced by inherent assume_init_mut method; will eventually be removed", + since = "1.83.0" + )] pub const unsafe fn slice_assume_init_mut(slice: &mut [Self]) -> &mut [T] { - // SAFETY: similar to safety notes for `slice_get_ref`, but we have a - // mutable reference which is also guaranteed to be valid for writes. - unsafe { &mut *(slice as *mut [Self] as *mut [T]) } + // SAFETY: Same for both methods. + unsafe { slice.assume_init_mut() } } /// Gets a pointer to the first element of the array. @@ -1015,142 +1078,34 @@ impl MaybeUninit { this.as_mut_ptr() as *mut T } - /// Copies the elements from `src` to `this`, returning a mutable reference to the now initialized contents of `this`. - /// - /// If `T` does not implement `Copy`, use [`clone_from_slice`] - /// - /// This is similar to [`slice::copy_from_slice`]. - /// - /// # Panics - /// - /// This function will panic if the two slices have different lengths. - /// - /// # Examples - /// - /// ``` - /// #![feature(maybe_uninit_write_slice)] - /// use std::mem::MaybeUninit; - /// - /// let mut dst = [MaybeUninit::uninit(); 32]; - /// let src = [0; 32]; - /// - /// let init = MaybeUninit::copy_from_slice(&mut dst, &src); - /// - /// assert_eq!(init, src); - /// ``` - /// - /// ``` - /// #![feature(maybe_uninit_write_slice)] - /// use std::mem::MaybeUninit; - /// - /// let mut vec = Vec::with_capacity(32); - /// let src = [0; 16]; - /// - /// MaybeUninit::copy_from_slice(&mut vec.spare_capacity_mut()[..src.len()], &src); - /// - /// // SAFETY: we have just copied all the elements of len into the spare capacity - /// // the first src.len() elements of the vec are valid now. - /// unsafe { - /// vec.set_len(src.len()); - /// } - /// - /// assert_eq!(vec, src); - /// ``` - /// - /// [`clone_from_slice`]: MaybeUninit::clone_from_slice + /// Deprecated version of [`slice::write_copy_of_slice`]. #[unstable(feature = "maybe_uninit_write_slice", issue = "79995")] + #[deprecated( + note = "replaced by inherent write_copy_of_slice method; will eventually be removed", + since = "1.83.0" + )] pub fn copy_from_slice<'a>(this: &'a mut [MaybeUninit], src: &[T]) -> &'a mut [T] where T: Copy, { - // SAFETY: &[T] and &[MaybeUninit] have the same layout - let uninit_src: &[MaybeUninit] = unsafe { super::transmute(src) }; - - this.copy_from_slice(uninit_src); - - // SAFETY: Valid elements have just been copied into `this` so it is initialized - unsafe { MaybeUninit::slice_assume_init_mut(this) } + this.write_copy_of_slice(src) } - /// Clones the elements from `src` to `this`, returning a mutable reference to the now initialized contents of `this`. - /// Any already initialized elements will not be dropped. - /// - /// If `T` implements `Copy`, use [`copy_from_slice`] - /// - /// This is similar to [`slice::clone_from_slice`] but does not drop existing elements. - /// - /// # Panics - /// - /// This function will panic if the two slices have different lengths, or if the implementation of `Clone` panics. - /// - /// If there is a panic, the already cloned elements will be dropped. - /// - /// # Examples - /// - /// ``` - /// #![feature(maybe_uninit_write_slice)] - /// use std::mem::MaybeUninit; - /// - /// let mut dst = [MaybeUninit::uninit(), MaybeUninit::uninit(), MaybeUninit::uninit(), MaybeUninit::uninit(), MaybeUninit::uninit()]; - /// let src = ["wibbly".to_string(), "wobbly".to_string(), "timey".to_string(), "wimey".to_string(), "stuff".to_string()]; - /// - /// let init = MaybeUninit::clone_from_slice(&mut dst, &src); - /// - /// assert_eq!(init, src); - /// # // Prevent leaks for Miri - /// # unsafe { std::ptr::drop_in_place(init); } - /// ``` - /// - /// ``` - /// #![feature(maybe_uninit_write_slice)] - /// use std::mem::MaybeUninit; - /// - /// let mut vec = Vec::with_capacity(32); - /// let src = ["rust", "is", "a", "pretty", "cool", "language"]; - /// - /// MaybeUninit::clone_from_slice(&mut vec.spare_capacity_mut()[..src.len()], &src); - /// - /// // SAFETY: we have just cloned all the elements of len into the spare capacity - /// // the first src.len() elements of the vec are valid now. - /// unsafe { - /// vec.set_len(src.len()); - /// } - /// - /// assert_eq!(vec, src); - /// ``` - /// - /// [`copy_from_slice`]: MaybeUninit::copy_from_slice + /// Deprecated version of [`slice::write_clone_of_slice`]. #[unstable(feature = "maybe_uninit_write_slice", issue = "79995")] + #[deprecated( + note = "replaced by inherent write_clone_of_slice method; will eventually be removed", + since = "1.83.0" + )] pub fn clone_from_slice<'a>(this: &'a mut [MaybeUninit], src: &[T]) -> &'a mut [T] where T: Clone, { - // unlike copy_from_slice this does not call clone_from_slice on the slice - // this is because `MaybeUninit` does not implement Clone. - - assert_eq!(this.len(), src.len(), "destination and source slices have different lengths"); - // NOTE: We need to explicitly slice them to the same length - // for bounds checking to be elided, and the optimizer will - // generate memcpy for simple cases (for example T = u8). - let len = this.len(); - let src = &src[..len]; - - // guard is needed b/c panic might happen during a clone - let mut guard = Guard { slice: this, initialized: 0 }; - - for i in 0..len { - guard.slice[i].write(src[i].clone()); - guard.initialized += 1; - } - - super::forget(guard); - - // SAFETY: Valid elements have just been written into `this` so it is initialized - unsafe { MaybeUninit::slice_assume_init_mut(this) } + this.write_clone_of_slice(src) } - /// Fills `this` with elements by cloning `value`, returning a mutable reference to the now - /// initialized contents of `this`. + /// Fills a slice with elements by cloning `value`, returning a mutable reference to the now + /// initialized contents of the slice. /// Any previously initialized elements will not be dropped. /// /// This is similar to [`slice::fill`]. @@ -1164,27 +1119,26 @@ impl MaybeUninit { /// /// # Examples /// - /// Fill an uninit vec with 1. /// ``` /// #![feature(maybe_uninit_fill)] /// use std::mem::MaybeUninit; /// - /// let mut buf = vec![MaybeUninit::uninit(); 10]; - /// let initialized = MaybeUninit::fill(buf.as_mut_slice(), 1); + /// let mut buf = [const { MaybeUninit::uninit() }; 10]; + /// let initialized = MaybeUninit::fill(&mut buf, 1); /// assert_eq!(initialized, &mut [1; 10]); /// ``` #[doc(alias = "memset")] #[unstable(feature = "maybe_uninit_fill", issue = "117428")] - pub fn fill<'a>(this: &'a mut [MaybeUninit], value: T) -> &'a mut [T] + pub fn fill(this: &mut [MaybeUninit], value: T) -> &mut [T] where T: Clone, { SpecFill::spec_fill(this, value); // SAFETY: Valid elements have just been filled into `this` so it is initialized - unsafe { MaybeUninit::slice_assume_init_mut(this) } + unsafe { this.assume_init_mut() } } - /// Fills `this` with elements returned by calling a closure repeatedly. + /// Fills a slice with elements returned by calling a closure repeatedly. /// /// This method uses a closure to create new values. If you'd rather `Clone` a given value, use /// [`MaybeUninit::fill`]. If you want to use the `Default` trait to generate values, you can @@ -1199,17 +1153,16 @@ impl MaybeUninit { /// /// # Examples /// - /// Fill an uninit vec with the default value. /// ``` /// #![feature(maybe_uninit_fill)] /// use std::mem::MaybeUninit; /// - /// let mut buf = vec![MaybeUninit::::uninit(); 10]; - /// let initialized = MaybeUninit::fill_with(buf.as_mut_slice(), Default::default); + /// let mut buf = [const { MaybeUninit::::uninit() }; 10]; + /// let initialized = MaybeUninit::fill_with(&mut buf, Default::default); /// assert_eq!(initialized, &mut [0; 10]); /// ``` #[unstable(feature = "maybe_uninit_fill", issue = "117428")] - pub fn fill_with<'a, F>(this: &'a mut [MaybeUninit], mut f: F) -> &'a mut [T] + pub fn fill_with(this: &mut [MaybeUninit], mut f: F) -> &mut [T] where F: FnMut() -> T, { @@ -1223,13 +1176,13 @@ impl MaybeUninit { super::forget(guard); // SAFETY: Valid elements have just been written into `this` so it is initialized - unsafe { MaybeUninit::slice_assume_init_mut(this) } + unsafe { this.assume_init_mut() } } - /// Fills `this` with elements yielded by an iterator until either all elements have been + /// Fills a slice with elements yielded by an iterator until either all elements have been /// initialized or the iterator is empty. /// - /// Returns two slices. The first slice contains the initialized portion of the original slice. + /// Returns two slices. The first slice contains the initialized portion of the original slice. /// The second slice is the still-uninitialized remainder of the original slice. /// /// # Panics @@ -1241,37 +1194,51 @@ impl MaybeUninit { /// /// # Examples /// - /// Fill an uninit vec with a cycling iterator. + /// Completely filling the slice: + /// /// ``` /// #![feature(maybe_uninit_fill)] /// use std::mem::MaybeUninit; /// - /// let mut buf = vec![MaybeUninit::uninit(); 5]; + /// let mut buf = [const { MaybeUninit::uninit() }; 5]; /// /// let iter = [1, 2, 3].into_iter().cycle(); /// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter); /// /// assert_eq!(initialized, &mut [1, 2, 3, 1, 2]); - /// assert_eq!(0, remainder.len()); + /// assert_eq!(remainder.len(), 0); /// ``` /// - /// Fill an uninit vec, but not completely. + /// Partially filling the slice: + /// /// ``` /// #![feature(maybe_uninit_fill)] /// use std::mem::MaybeUninit; /// - /// let mut buf = vec![MaybeUninit::uninit(); 5]; + /// let mut buf = [const { MaybeUninit::uninit() }; 5]; /// let iter = [1, 2]; /// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter); /// /// assert_eq!(initialized, &mut [1, 2]); /// assert_eq!(remainder.len(), 3); /// ``` + /// + /// Checking an iterator after filling a slice: + /// + /// ``` + /// #![feature(maybe_uninit_fill)] + /// use std::mem::MaybeUninit; + /// + /// let mut buf = [const { MaybeUninit::uninit() }; 3]; + /// let mut iter = [1, 2, 3, 4, 5].into_iter(); + /// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter.by_ref()); + /// + /// assert_eq!(initialized, &mut [1, 2, 3]); + /// assert_eq!(remainder.len(), 0); + /// assert_eq!(iter.as_slice(), &[4, 5]); + /// ``` #[unstable(feature = "maybe_uninit_fill", issue = "117428")] - pub fn fill_from<'a, I>( - this: &'a mut [MaybeUninit], - it: I, - ) -> (&'a mut [T], &'a mut [MaybeUninit]) + pub fn fill_from(this: &mut [MaybeUninit], it: I) -> (&mut [T], &mut [MaybeUninit]) where I: IntoIterator, { @@ -1291,70 +1258,169 @@ impl MaybeUninit { // SAFETY: Valid elements have just been written into `init`, so that portion // of `this` is initialized. - (unsafe { MaybeUninit::slice_assume_init_mut(initted) }, remainder) + (unsafe { initted.assume_init_mut() }, remainder) } - /// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes. + /// Deprecated version of [`slice::as_bytes`]. + #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")] + #[deprecated( + note = "replaced by inherent as_bytes method; will eventually be removed", + since = "1.83.0" + )] + pub fn slice_as_bytes(this: &[MaybeUninit]) -> &[MaybeUninit] { + this.as_bytes() + } + + /// Deprecated version of [`slice::as_bytes_mut`]. + #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")] + #[deprecated( + note = "replaced by inherent as_bytes_mut method; will eventually be removed", + since = "1.83.0" + )] + pub fn slice_as_bytes_mut(this: &mut [MaybeUninit]) -> &mut [MaybeUninit] { + this.as_bytes_mut() + } +} + +impl [MaybeUninit] { + /// Copies the elements from `src` to `self`, + /// returning a mutable reference to the now initialized contents of `self`. /// - /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still - /// contain padding bytes which are left uninitialized. + /// If `T` does not implement `Copy`, use [`write_clone_of_slice`] instead. + /// + /// This is similar to [`slice::copy_from_slice`]. + /// + /// # Panics + /// + /// This function will panic if the two slices have different lengths. /// /// # Examples /// /// ``` - /// #![feature(maybe_uninit_as_bytes, maybe_uninit_slice)] + /// #![feature(maybe_uninit_write_slice)] /// use std::mem::MaybeUninit; /// - /// let val = 0x12345678_i32; - /// let uninit = MaybeUninit::new(val); - /// let uninit_bytes = uninit.as_bytes(); - /// let bytes = unsafe { MaybeUninit::slice_assume_init_ref(uninit_bytes) }; - /// assert_eq!(bytes, val.to_ne_bytes()); + /// let mut dst = [MaybeUninit::uninit(); 32]; + /// let src = [0; 32]; + /// + /// let init = dst.write_copy_of_slice(&src); + /// + /// assert_eq!(init, src); /// ``` - #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")] - pub fn as_bytes(&self) -> &[MaybeUninit] { - // SAFETY: MaybeUninit is always valid, even for padding bytes - unsafe { - slice::from_raw_parts(self.as_ptr() as *const MaybeUninit, mem::size_of::()) - } + /// + /// ``` + /// #![feature(maybe_uninit_write_slice)] + /// + /// let mut vec = Vec::with_capacity(32); + /// let src = [0; 16]; + /// + /// vec.spare_capacity_mut()[..src.len()].write_copy_of_slice(&src); + /// + /// // SAFETY: we have just copied all the elements of len into the spare capacity + /// // the first src.len() elements of the vec are valid now. + /// unsafe { + /// vec.set_len(src.len()); + /// } + /// + /// assert_eq!(vec, src); + /// ``` + /// + /// [`write_clone_of_slice`]: slice::write_clone_of_slice + #[unstable(feature = "maybe_uninit_write_slice", issue = "79995")] + #[rustc_const_unstable(feature = "maybe_uninit_write_slice", issue = "79995")] + pub const fn write_copy_of_slice(&mut self, src: &[T]) -> &mut [T] + where + T: Copy, + { + // SAFETY: &[T] and &[MaybeUninit] have the same layout + let uninit_src: &[MaybeUninit] = unsafe { super::transmute(src) }; + + self.copy_from_slice(uninit_src); + + // SAFETY: Valid elements have just been copied into `self` so it is initialized + unsafe { self.assume_init_mut() } } - /// Returns the contents of this `MaybeUninit` as a mutable slice of potentially uninitialized - /// bytes. + /// Clones the elements from `src` to `self`, + /// returning a mutable reference to the now initialized contents of `self`. + /// Any already initialized elements will not be dropped. /// - /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still - /// contain padding bytes which are left uninitialized. + /// If `T` implements `Copy`, use [`write_copy_of_slice`] instead. + /// + /// This is similar to [`slice::clone_from_slice`] but does not drop existing elements. + /// + /// # Panics + /// + /// This function will panic if the two slices have different lengths, or if the implementation of `Clone` panics. + /// + /// If there is a panic, the already cloned elements will be dropped. /// /// # Examples /// /// ``` - /// #![feature(maybe_uninit_as_bytes)] + /// #![feature(maybe_uninit_write_slice)] /// use std::mem::MaybeUninit; /// - /// let val = 0x12345678_i32; - /// let mut uninit = MaybeUninit::new(val); - /// let uninit_bytes = uninit.as_bytes_mut(); - /// if cfg!(target_endian = "little") { - /// uninit_bytes[0].write(0xcd); - /// } else { - /// uninit_bytes[3].write(0xcd); + /// let mut dst = [const { MaybeUninit::uninit() }; 5]; + /// let src = ["wibbly", "wobbly", "timey", "wimey", "stuff"].map(|s| s.to_string()); + /// + /// let init = dst.write_clone_of_slice(&src); + /// + /// assert_eq!(init, src); + /// + /// # // Prevent leaks for Miri + /// # unsafe { std::ptr::drop_in_place(init); } + /// ``` + /// + /// ``` + /// #![feature(maybe_uninit_write_slice)] + /// + /// let mut vec = Vec::with_capacity(32); + /// let src = ["rust", "is", "a", "pretty", "cool", "language"].map(|s| s.to_string()); + /// + /// vec.spare_capacity_mut()[..src.len()].write_clone_of_slice(&src); + /// + /// // SAFETY: we have just cloned all the elements of len into the spare capacity + /// // the first src.len() elements of the vec are valid now. + /// unsafe { + /// vec.set_len(src.len()); /// } - /// let val2 = unsafe { uninit.assume_init() }; - /// assert_eq!(val2, 0x123456cd); + /// + /// assert_eq!(vec, src); /// ``` - #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")] - pub fn as_bytes_mut(&mut self) -> &mut [MaybeUninit] { - // SAFETY: MaybeUninit is always valid, even for padding bytes - unsafe { - slice::from_raw_parts_mut( - self.as_mut_ptr() as *mut MaybeUninit, - mem::size_of::(), - ) + /// + /// [`write_copy_of_slice`]: slice::write_copy_of_slice + #[unstable(feature = "maybe_uninit_write_slice", issue = "79995")] + pub fn write_clone_of_slice(&mut self, src: &[T]) -> &mut [T] + where + T: Clone, + { + // unlike copy_from_slice this does not call clone_from_slice on the slice + // this is because `MaybeUninit` does not implement Clone. + + assert_eq!(self.len(), src.len(), "destination and source slices have different lengths"); + + // NOTE: We need to explicitly slice them to the same length + // for bounds checking to be elided, and the optimizer will + // generate memcpy for simple cases (for example T = u8). + let len = self.len(); + let src = &src[..len]; + + // guard is needed b/c panic might happen during a clone + let mut guard = Guard { slice: self, initialized: 0 }; + + for i in 0..len { + guard.slice[i].write(src[i].clone()); + guard.initialized += 1; } + + super::forget(guard); + + // SAFETY: Valid elements have just been written into `self` so it is initialized + unsafe { self.assume_init_mut() } } - /// Returns the contents of this slice of `MaybeUninit` as a slice of potentially uninitialized - /// bytes. + /// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes. /// /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still /// contain padding bytes which are left uninitialized. @@ -1366,21 +1432,22 @@ impl MaybeUninit { /// use std::mem::MaybeUninit; /// /// let uninit = [MaybeUninit::new(0x1234u16), MaybeUninit::new(0x5678u16)]; - /// let uninit_bytes = MaybeUninit::slice_as_bytes(&uninit); - /// let bytes = unsafe { MaybeUninit::slice_assume_init_ref(&uninit_bytes) }; + /// let uninit_bytes = uninit.as_bytes(); + /// let bytes = unsafe { uninit_bytes.assume_init_ref() }; /// let val1 = u16::from_ne_bytes(bytes[0..2].try_into().unwrap()); /// let val2 = u16::from_ne_bytes(bytes[2..4].try_into().unwrap()); /// assert_eq!(&[val1, val2], &[0x1234u16, 0x5678u16]); /// ``` #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")] - pub fn slice_as_bytes(this: &[MaybeUninit]) -> &[MaybeUninit] { - let bytes = mem::size_of_val(this); + pub const fn as_bytes(&self) -> &[MaybeUninit] { // SAFETY: MaybeUninit is always valid, even for padding bytes - unsafe { slice::from_raw_parts(this.as_ptr() as *const MaybeUninit, bytes) } + unsafe { + slice::from_raw_parts(self.as_ptr().cast::>(), super::size_of_val(self)) + } } - /// Returns the contents of this mutable slice of `MaybeUninit` as a mutable slice of - /// potentially uninitialized bytes. + /// Returns the contents of this `MaybeUninit` slice as a mutable slice of potentially + /// uninitialized bytes. /// /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still /// contain padding bytes which are left uninitialized. @@ -1393,8 +1460,8 @@ impl MaybeUninit { /// /// let mut uninit = [MaybeUninit::::uninit(), MaybeUninit::::uninit()]; /// let uninit_bytes = MaybeUninit::slice_as_bytes_mut(&mut uninit); - /// MaybeUninit::copy_from_slice(uninit_bytes, &[0x12, 0x34, 0x56, 0x78]); - /// let vals = unsafe { MaybeUninit::slice_assume_init_ref(&uninit) }; + /// uninit_bytes.write_copy_of_slice(&[0x12, 0x34, 0x56, 0x78]); + /// let vals = unsafe { uninit.assume_init_ref() }; /// if cfg!(target_endian = "little") { /// assert_eq!(vals, &[0x3412u16, 0x7856u16]); /// } else { @@ -1402,10 +1469,74 @@ impl MaybeUninit { /// } /// ``` #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")] - pub fn slice_as_bytes_mut(this: &mut [MaybeUninit]) -> &mut [MaybeUninit] { - let bytes = mem::size_of_val(this); + pub const fn as_bytes_mut(&mut self) -> &mut [MaybeUninit] { // SAFETY: MaybeUninit is always valid, even for padding bytes - unsafe { slice::from_raw_parts_mut(this.as_mut_ptr() as *mut MaybeUninit, bytes) } + unsafe { + slice::from_raw_parts_mut( + self.as_mut_ptr() as *mut MaybeUninit, + super::size_of_val(self), + ) + } + } + + /// Drops the contained values in place. + /// + /// # Safety + /// + /// It is up to the caller to guarantee that every `MaybeUninit` in the slice + /// really is in an initialized state. Calling this when the content is not yet + /// fully initialized causes undefined behavior. + /// + /// On top of that, all additional invariants of the type `T` must be + /// satisfied, as the `Drop` implementation of `T` (or its members) may + /// rely on this. For example, setting a `Vec` to an invalid but + /// non-null address makes it initialized (under the current implementation; + /// this does not constitute a stable guarantee), because the only + /// requirement the compiler knows about it is that the data pointer must be + /// non-null. Dropping such a `Vec` however will cause undefined + /// behaviour. + #[unstable(feature = "maybe_uninit_slice", issue = "63569")] + #[inline(always)] + pub unsafe fn assume_init_drop(&mut self) { + if !self.is_empty() { + // SAFETY: the caller must guarantee that every element of `self` + // is initialized and satisfies all invariants of `T`. + // Dropping the value in place is safe if that is the case. + unsafe { ptr::drop_in_place(self as *mut [MaybeUninit] as *mut [T]) } + } + } + + /// Gets a shared reference to the contained value. + /// + /// # Safety + /// + /// Calling this when the content is not yet fully initialized causes undefined + /// behavior: it is up to the caller to guarantee that every `MaybeUninit` in + /// the slice really is in an initialized state. + #[unstable(feature = "maybe_uninit_slice", issue = "63569")] + #[inline(always)] + pub const unsafe fn assume_init_ref(&self) -> &[T] { + // SAFETY: casting `slice` to a `*const [T]` is safe since the caller guarantees that + // `slice` is initialized, and `MaybeUninit` is guaranteed to have the same layout as `T`. + // The pointer obtained is valid since it refers to memory owned by `slice` which is a + // reference and thus guaranteed to be valid for reads. + unsafe { &*(self as *const Self as *const [T]) } + } + + /// Gets a mutable (unique) reference to the contained value. + /// + /// # Safety + /// + /// Calling this when the content is not yet fully initialized causes undefined + /// behavior: it is up to the caller to guarantee that every `MaybeUninit` in the + /// slice really is in an initialized state. For instance, `.assume_init_mut()` cannot + /// be used to initialize a `MaybeUninit` slice. + #[unstable(feature = "maybe_uninit_slice", issue = "63569")] + #[inline(always)] + pub const unsafe fn assume_init_mut(&mut self) -> &mut [T] { + // SAFETY: similar to safety notes for `slice_get_ref`, but we have a + // mutable reference which is also guaranteed to be valid for writes. + unsafe { &mut *(self as *mut Self as *mut [T]) } } } @@ -1458,7 +1589,7 @@ impl<'a, T> Drop for Guard<'a, T> { let initialized_part = &mut self.slice[..self.initialized]; // SAFETY: this raw sub-slice will contain only initialized objects. unsafe { - crate::ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(initialized_part)); + initialized_part.assume_init_drop(); } } } diff --git a/core/src/mem/mod.rs b/core/src/mem/mod.rs index 4cf52042a57f6..b9bb6d6a13f7f 100644 --- a/core/src/mem/mod.rs +++ b/core/src/mem/mod.rs @@ -333,7 +333,7 @@ pub const fn size_of() -> usize { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_size_of_val", issue = "46571")] +#[rustc_const_stable(feature = "const_size_of_val", since = "1.85.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "mem_size_of_val")] pub const fn size_of_val(val: &T) -> usize { // SAFETY: `val` is a reference, so it's a valid raw pointer @@ -390,7 +390,6 @@ pub const fn size_of_val(val: &T) -> usize { #[inline] #[must_use] #[unstable(feature = "layout_for_ptr", issue = "69835")] -#[rustc_const_unstable(feature = "const_size_of_val_raw", issue = "46571")] pub const unsafe fn size_of_val_raw(val: *const T) -> usize { // SAFETY: the caller must provide a valid raw pointer unsafe { intrinsics::size_of_val(val) } @@ -485,7 +484,7 @@ pub const fn align_of() -> usize { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_align_of_val", issue = "46571")] +#[rustc_const_stable(feature = "const_align_of_val", since = "1.85.0")] #[allow(deprecated)] pub const fn align_of_val(val: &T) -> usize { // SAFETY: val is a reference, so it's a valid raw pointer @@ -534,7 +533,6 @@ pub const fn align_of_val(val: &T) -> usize { #[inline] #[must_use] #[unstable(feature = "layout_for_ptr", issue = "69835")] -#[rustc_const_unstable(feature = "const_align_of_val_raw", issue = "46571")] pub const unsafe fn align_of_val_raw(val: *const T) -> usize { // SAFETY: the caller must provide a valid raw pointer unsafe { intrinsics::min_align_of_val(val) } @@ -727,12 +725,12 @@ pub unsafe fn uninitialized() -> T { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_swap", issue = "83163")] +#[rustc_const_stable(feature = "const_swap", since = "1.85.0")] #[rustc_diagnostic_item = "mem_swap"] pub const fn swap(x: &mut T, y: &mut T) { // SAFETY: `&mut` guarantees these are typed readable and writable // as well as non-overlapping. - unsafe { intrinsics::typed_swap(x, y) } + unsafe { intrinsics::typed_swap_nonoverlapping(x, y) } } /// Replaces `dest` with the default value of `T`, returning the previous `dest` value. @@ -1243,6 +1241,17 @@ pub trait SizedTypeProperties: Sized { #[doc(hidden)] #[unstable(feature = "sized_type_properties", issue = "none")] const LAYOUT: Layout = Layout::new::(); + + /// The largest safe length for a `[Self]`. + /// + /// Anything larger than this would make `size_of_val` overflow `isize::MAX`, + /// which is never allowed for a single object. + #[doc(hidden)] + #[unstable(feature = "sized_type_properties", issue = "none")] + const MAX_SLICE_LEN: usize = match size_of::() { + 0 => usize::MAX, + n => (isize::MAX as usize) / n, + }; } #[doc(hidden)] #[unstable(feature = "sized_type_properties", issue = "none")] diff --git a/core/src/mem/transmutability.rs b/core/src/mem/transmutability.rs index 7fa3c33439170..6a4f84c849cb1 100644 --- a/core/src/mem/transmutability.rs +++ b/core/src/mem/transmutability.rs @@ -84,7 +84,8 @@ use crate::marker::{ConstParamTy_, UnsizedConstParamTy}; /// `usize` is stable, but not portable. #[unstable(feature = "transmutability", issue = "99571")] #[lang = "transmute_trait"] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[rustc_deny_explicit_impl] +#[rustc_do_not_implement_via_object] #[rustc_coinductive] pub unsafe trait TransmuteFrom where diff --git a/core/src/net/display_buffer.rs b/core/src/net/display_buffer.rs index bab84a97308b3..a7d12217081f6 100644 --- a/core/src/net/display_buffer.rs +++ b/core/src/net/display_buffer.rs @@ -18,7 +18,7 @@ impl DisplayBuffer { // SAFETY: `buf` is only written to by the `fmt::Write::write_str` implementation // which writes a valid UTF-8 string to `buf` and correctly sets `len`. unsafe { - let s = MaybeUninit::slice_assume_init_ref(&self.buf[..self.len]); + let s = self.buf[..self.len].assume_init_ref(); str::from_utf8_unchecked(s) } } @@ -29,7 +29,7 @@ impl fmt::Write for DisplayBuffer { let bytes = s.as_bytes(); if let Some(buf) = self.buf.get_mut(self.len..(self.len + bytes.len())) { - MaybeUninit::copy_from_slice(buf, bytes); + buf.write_copy_of_slice(bytes); self.len += bytes.len(); Ok(()) } else { diff --git a/core/src/net/ip_addr.rs b/core/src/net/ip_addr.rs index 6746f0b2b316b..7dd5c21401264 100644 --- a/core/src/net/ip_addr.rs +++ b/core/src/net/ip_addr.rs @@ -527,7 +527,7 @@ impl Ipv4Addr { /// ``` /// use std::net::Ipv4Addr; /// - /// let addr = Ipv4Addr::from(0x12345678); + /// let addr = Ipv4Addr::from_bits(0x12345678); /// assert_eq!(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78), addr); /// ``` #[rustc_const_stable(feature = "ip_bits", since = "1.80.0")] @@ -1294,7 +1294,7 @@ impl Ipv6Addr { /// 0x1020, 0x3040, 0x5060, 0x7080, /// 0x90A0, 0xB0C0, 0xD0E0, 0xF00D, /// ); - /// assert_eq!(0x102030405060708090A0B0C0D0E0F00D_u128, u128::from(addr)); + /// assert_eq!(0x102030405060708090A0B0C0D0E0F00D_u128, addr.to_bits()); /// ``` /// /// ``` @@ -1330,7 +1330,7 @@ impl Ipv6Addr { /// ``` /// use std::net::Ipv6Addr; /// - /// let addr = Ipv6Addr::from(0x102030405060708090A0B0C0D0E0F00D_u128); + /// let addr = Ipv6Addr::from_bits(0x102030405060708090A0B0C0D0E0F00D_u128); /// assert_eq!( /// Ipv6Addr::new( /// 0x1020, 0x3040, 0x5060, 0x7080, @@ -1601,8 +1601,8 @@ impl Ipv6Addr { /// ``` #[must_use] #[inline] - #[stable(feature = "ipv6_is_unique_local", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "ipv6_is_unique_local", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "ipv6_is_unique_local", since = "1.84.0")] + #[rustc_const_stable(feature = "ipv6_is_unique_local", since = "1.84.0")] pub const fn is_unique_local(&self) -> bool { (self.segments()[0] & 0xfe00) == 0xfc00 } @@ -1679,8 +1679,8 @@ impl Ipv6Addr { /// ``` #[must_use] #[inline] - #[stable(feature = "ipv6_is_unique_local", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "ipv6_is_unique_local", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "ipv6_is_unique_local", since = "1.84.0")] + #[rustc_const_stable(feature = "ipv6_is_unique_local", since = "1.84.0")] pub const fn is_unicast_link_local(&self) -> bool { (self.segments()[0] & 0xffc0) == 0xfe80 } diff --git a/core/src/num/f128.rs b/core/src/num/f128.rs index abeccb7eea248..4ebeaf046114a 100644 --- a/core/src/num/f128.rs +++ b/core/src/num/f128.rs @@ -807,7 +807,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// #![feature(num_midpoint)] /// # // Using aarch64 because `reliable_f128_math` is needed /// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] { /// @@ -817,8 +816,8 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] - // #[unstable(feature = "num_midpoint", issue = "110840")] - pub fn midpoint(self, other: f128) -> f128 { + #[rustc_const_unstable(feature = "f128", issue = "116909")] + pub const fn midpoint(self, other: f128) -> f128 { const LO: f128 = f128::MIN_POSITIVE * 2.; const HI: f128 = f128::MAX / 2.; diff --git a/core/src/num/f16.rs b/core/src/num/f16.rs index 0d3e92695707c..c82f0d7cd4ad5 100644 --- a/core/src/num/f16.rs +++ b/core/src/num/f16.rs @@ -795,7 +795,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// #![feature(num_midpoint)] /// # #[cfg(target_arch = "aarch64")] { // FIXME(f16_F128): rust-lang/rust#123885 /// /// assert_eq!(1f16.midpoint(4.0), 2.5); @@ -804,8 +803,8 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] - // #[unstable(feature = "num_midpoint", issue = "110840")] - pub fn midpoint(self, other: f16) -> f16 { + #[rustc_const_unstable(feature = "f16", issue = "116909")] + pub const fn midpoint(self, other: f16) -> f16 { const LO: f16 = f16::MIN_POSITIVE * 2.; const HI: f16 = f16::MAX / 2.; diff --git a/core/src/num/f32.rs b/core/src/num/f32.rs index 47dfce7530fb7..2b6adef65e94a 100644 --- a/core/src/num/f32.rs +++ b/core/src/num/f32.rs @@ -818,7 +818,7 @@ impl f32 { /// ``` #[must_use = "this returns the result of the operation, without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn recip(self) -> f32 { 1.0 / self @@ -836,7 +836,7 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")] - #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn to_degrees(self) -> f32 { // Use a constant for better precision. @@ -856,7 +856,7 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")] - #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn to_radians(self) -> f32 { const RADS_PER_DEG: f32 = consts::PI / 180.0; @@ -878,7 +878,7 @@ impl f32 { /// ``` #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn max(self, other: f32) -> f32 { intrinsics::maxnumf32(self, other) @@ -899,7 +899,7 @@ impl f32 { /// ``` #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn min(self, other: f32) -> f32 { intrinsics::minnumf32(self, other) @@ -984,27 +984,27 @@ impl f32 { /// # Examples /// /// ``` - /// #![feature(num_midpoint)] /// assert_eq!(1f32.midpoint(4.0), 2.5); /// assert_eq!((-5.5f32).midpoint(8.0), 1.25); /// ``` #[inline] - #[unstable(feature = "num_midpoint", issue = "110840")] - pub fn midpoint(self, other: f32) -> f32 { + #[stable(feature = "num_midpoint", since = "1.85.0")] + #[rustc_const_stable(feature = "num_midpoint", since = "1.85.0")] + pub const fn midpoint(self, other: f32) -> f32 { cfg_if! { + // Allow faster implementation that have known good 64-bit float + // implementations. Falling back to the branchy code on targets that don't + // have 64-bit hardware floats or buggy implementations. + // https://github.com/rust-lang/rust/pull/121062#issuecomment-2123408114 if #[cfg(any( target_arch = "x86_64", target_arch = "aarch64", - all(any(target_arch="riscv32", target_arch= "riscv64"), target_feature="d"), - all(target_arch = "arm", target_feature="vfp2"), + all(any(target_arch = "riscv32", target_arch = "riscv64"), target_feature = "d"), + all(target_arch = "arm", target_feature = "vfp2"), target_arch = "wasm32", target_arch = "wasm64", ))] { - // whitelist the faster implementation to targets that have known good 64-bit float - // implementations. Falling back to the branchy code on targets that don't have - // 64-bit hardware floats or buggy implementations. - // see: https://github.com/rust-lang/rust/pull/121062#issuecomment-2123408114 - ((f64::from(self) + f64::from(other)) / 2.0) as f32 + ((self as f64 + other as f64) / 2.0) as f32 } else { const LO: f32 = f32::MIN_POSITIVE * 2.; const HI: f32 = f32::MAX / 2.; @@ -1396,7 +1396,7 @@ impl f32 { /// ``` #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "clamp", since = "1.50.0")] - #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn clamp(mut self, min: f32, max: f32) -> f32 { const_assert!( @@ -1433,7 +1433,7 @@ impl f32 { /// ``` #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn abs(self) -> f32 { // SAFETY: this is actually a safe intrinsic @@ -1458,7 +1458,7 @@ impl f32 { /// ``` #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn signum(self) -> f32 { if self.is_nan() { Self::NAN } else { 1.0_f32.copysign(self) } @@ -1493,7 +1493,7 @@ impl f32 { #[must_use = "method returns a new number and does not mutate the original value"] #[inline] #[stable(feature = "copysign", since = "1.35.0")] - #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] pub const fn copysign(self, sign: f32) -> f32 { // SAFETY: this is actually a safe intrinsic unsafe { intrinsics::copysignf32(self, sign) } diff --git a/core/src/num/f64.rs b/core/src/num/f64.rs index c89023c1ae490..037b3afa6c46c 100644 --- a/core/src/num/f64.rs +++ b/core/src/num/f64.rs @@ -835,7 +835,7 @@ impl f64 { /// ``` #[must_use = "this returns the result of the operation, without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn recip(self) -> f64 { 1.0 / self @@ -853,7 +853,7 @@ impl f64 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn to_degrees(self) -> f64 { // The division here is correctly rounded with respect to the true @@ -874,7 +874,7 @@ impl f64 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn to_radians(self) -> f64 { const RADS_PER_DEG: f64 = consts::PI / 180.0; @@ -896,7 +896,7 @@ impl f64 { /// ``` #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn max(self, other: f64) -> f64 { intrinsics::maxnumf64(self, other) @@ -917,7 +917,7 @@ impl f64 { /// ``` #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn min(self, other: f64) -> f64 { intrinsics::minnumf64(self, other) @@ -1002,13 +1002,13 @@ impl f64 { /// # Examples /// /// ``` - /// #![feature(num_midpoint)] /// assert_eq!(1f64.midpoint(4.0), 2.5); /// assert_eq!((-5.5f64).midpoint(8.0), 1.25); /// ``` #[inline] - #[unstable(feature = "num_midpoint", issue = "110840")] - pub fn midpoint(self, other: f64) -> f64 { + #[stable(feature = "num_midpoint", since = "1.85.0")] + #[rustc_const_stable(feature = "num_midpoint", since = "1.85.0")] + pub const fn midpoint(self, other: f64) -> f64 { const LO: f64 = f64::MIN_POSITIVE * 2.; const HI: f64 = f64::MAX / 2.; @@ -1396,7 +1396,7 @@ impl f64 { /// ``` #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "clamp", since = "1.50.0")] - #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn clamp(mut self, min: f64, max: f64) -> f64 { const_assert!( @@ -1433,7 +1433,7 @@ impl f64 { /// ``` #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn abs(self) -> f64 { // SAFETY: this is actually a safe intrinsic @@ -1458,7 +1458,7 @@ impl f64 { /// ``` #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn signum(self) -> f64 { if self.is_nan() { Self::NAN } else { 1.0_f64.copysign(self) } @@ -1492,7 +1492,7 @@ impl f64 { /// ``` #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "copysign", since = "1.35.0")] - #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn copysign(self, sign: f64) -> f64 { // SAFETY: this is actually a safe intrinsic diff --git a/core/src/num/flt2dec/mod.rs b/core/src/num/flt2dec/mod.rs index d6413fadc3381..7601e3e2c58a2 100644 --- a/core/src/num/flt2dec/mod.rs +++ b/core/src/num/flt2dec/mod.rs @@ -210,10 +210,10 @@ fn digits_to_dec_str<'a>( if frac_digits > buf.len() && frac_digits - buf.len() > minus_exp { parts[3] = MaybeUninit::new(Part::Zero((frac_digits - buf.len()) - minus_exp)); // SAFETY: we just initialized the elements `..4`. - unsafe { MaybeUninit::slice_assume_init_ref(&parts[..4]) } + unsafe { parts[..4].assume_init_ref() } } else { // SAFETY: we just initialized the elements `..3`. - unsafe { MaybeUninit::slice_assume_init_ref(&parts[..3]) } + unsafe { parts[..3].assume_init_ref() } } } else { let exp = exp as usize; @@ -225,10 +225,10 @@ fn digits_to_dec_str<'a>( if frac_digits > buf.len() - exp { parts[3] = MaybeUninit::new(Part::Zero(frac_digits - (buf.len() - exp))); // SAFETY: we just initialized the elements `..4`. - unsafe { MaybeUninit::slice_assume_init_ref(&parts[..4]) } + unsafe { parts[..4].assume_init_ref() } } else { // SAFETY: we just initialized the elements `..3`. - unsafe { MaybeUninit::slice_assume_init_ref(&parts[..3]) } + unsafe { parts[..3].assume_init_ref() } } } else { // the decimal point is after rendered digits: [1234][____0000] or [1234][__][.][__]. @@ -238,10 +238,10 @@ fn digits_to_dec_str<'a>( parts[2] = MaybeUninit::new(Part::Copy(b".")); parts[3] = MaybeUninit::new(Part::Zero(frac_digits)); // SAFETY: we just initialized the elements `..4`. - unsafe { MaybeUninit::slice_assume_init_ref(&parts[..4]) } + unsafe { parts[..4].assume_init_ref() } } else { // SAFETY: we just initialized the elements `..2`. - unsafe { MaybeUninit::slice_assume_init_ref(&parts[..2]) } + unsafe { parts[..2].assume_init_ref() } } } } @@ -292,7 +292,7 @@ fn digits_to_exp_str<'a>( parts[n + 1] = MaybeUninit::new(Part::Num(exp as u16)); } // SAFETY: we just initialized the elements `..n + 2`. - unsafe { MaybeUninit::slice_assume_init_ref(&parts[..n + 2]) } + unsafe { parts[..n + 2].assume_init_ref() } } /// Sign formatting options. @@ -366,12 +366,12 @@ where FullDecoded::Nan => { parts[0] = MaybeUninit::new(Part::Copy(b"NaN")); // SAFETY: we just initialized the elements `..1`. - Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } } + Formatted { sign, parts: unsafe { parts[..1].assume_init_ref() } } } FullDecoded::Infinite => { parts[0] = MaybeUninit::new(Part::Copy(b"inf")); // SAFETY: we just initialized the elements `..1`. - Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } } + Formatted { sign, parts: unsafe { parts[..1].assume_init_ref() } } } FullDecoded::Zero => { if frac_digits > 0 { @@ -381,14 +381,14 @@ where Formatted { sign, // SAFETY: we just initialized the elements `..2`. - parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..2]) }, + parts: unsafe { parts[..2].assume_init_ref() }, } } else { parts[0] = MaybeUninit::new(Part::Copy(b"0")); Formatted { sign, // SAFETY: we just initialized the elements `..1`. - parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) }, + parts: unsafe { parts[..1].assume_init_ref() }, } } } @@ -442,12 +442,12 @@ where FullDecoded::Nan => { parts[0] = MaybeUninit::new(Part::Copy(b"NaN")); // SAFETY: we just initialized the elements `..1`. - Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } } + Formatted { sign, parts: unsafe { parts[..1].assume_init_ref() } } } FullDecoded::Infinite => { parts[0] = MaybeUninit::new(Part::Copy(b"inf")); // SAFETY: we just initialized the elements `..1`. - Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } } + Formatted { sign, parts: unsafe { parts[..1].assume_init_ref() } } } FullDecoded::Zero => { parts[0] = if dec_bounds.0 <= 0 && 0 < dec_bounds.1 { @@ -456,7 +456,7 @@ where MaybeUninit::new(Part::Copy(if upper { b"0E0" } else { b"0e0" })) }; // SAFETY: we just initialized the elements `..1`. - Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } } + Formatted { sign, parts: unsafe { parts[..1].assume_init_ref() } } } FullDecoded::Finite(ref decoded) => { let (buf, exp) = format_shortest(decoded, buf); @@ -533,12 +533,12 @@ where FullDecoded::Nan => { parts[0] = MaybeUninit::new(Part::Copy(b"NaN")); // SAFETY: we just initialized the elements `..1`. - Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } } + Formatted { sign, parts: unsafe { parts[..1].assume_init_ref() } } } FullDecoded::Infinite => { parts[0] = MaybeUninit::new(Part::Copy(b"inf")); // SAFETY: we just initialized the elements `..1`. - Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } } + Formatted { sign, parts: unsafe { parts[..1].assume_init_ref() } } } FullDecoded::Zero => { if ndigits > 1 { @@ -549,14 +549,14 @@ where Formatted { sign, // SAFETY: we just initialized the elements `..3`. - parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..3]) }, + parts: unsafe { parts[..3].assume_init_ref() }, } } else { parts[0] = MaybeUninit::new(Part::Copy(if upper { b"0E0" } else { b"0e0" })); Formatted { sign, // SAFETY: we just initialized the elements `..1`. - parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) }, + parts: unsafe { parts[..1].assume_init_ref() }, } } } @@ -607,12 +607,12 @@ where FullDecoded::Nan => { parts[0] = MaybeUninit::new(Part::Copy(b"NaN")); // SAFETY: we just initialized the elements `..1`. - Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } } + Formatted { sign, parts: unsafe { parts[..1].assume_init_ref() } } } FullDecoded::Infinite => { parts[0] = MaybeUninit::new(Part::Copy(b"inf")); // SAFETY: we just initialized the elements `..1`. - Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } } + Formatted { sign, parts: unsafe { parts[..1].assume_init_ref() } } } FullDecoded::Zero => { if frac_digits > 0 { @@ -622,14 +622,14 @@ where Formatted { sign, // SAFETY: we just initialized the elements `..2`. - parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..2]) }, + parts: unsafe { parts[..2].assume_init_ref() }, } } else { parts[0] = MaybeUninit::new(Part::Copy(b"0")); Formatted { sign, // SAFETY: we just initialized the elements `..1`. - parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) }, + parts: unsafe { parts[..1].assume_init_ref() }, } } } @@ -654,14 +654,14 @@ where Formatted { sign, // SAFETY: we just initialized the elements `..2`. - parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..2]) }, + parts: unsafe { parts[..2].assume_init_ref() }, } } else { parts[0] = MaybeUninit::new(Part::Copy(b"0")); Formatted { sign, // SAFETY: we just initialized the elements `..1`. - parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) }, + parts: unsafe { parts[..1].assume_init_ref() }, } } } else { diff --git a/core/src/num/flt2dec/strategy/dragon.rs b/core/src/num/flt2dec/strategy/dragon.rs index e801f07b3bc0e..dd73e4b4846d5 100644 --- a/core/src/num/flt2dec/strategy/dragon.rs +++ b/core/src/num/flt2dec/strategy/dragon.rs @@ -247,7 +247,7 @@ pub fn format_shortest<'a>( // it seems that this condition is very hard to satisfy (possibly impossible), // but we are just being safe and consistent here. // SAFETY: we initialized that memory above. - if let Some(c) = round_up(unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..i]) }) { + if let Some(c) = round_up(unsafe { buf[..i].assume_init_mut() }) { buf[i] = MaybeUninit::new(c); i += 1; k += 1; @@ -255,7 +255,7 @@ pub fn format_shortest<'a>( } // SAFETY: we initialized that memory above. - (unsafe { MaybeUninit::slice_assume_init_ref(&buf[..i]) }, k) + (unsafe { buf[..i].assume_init_ref() }, k) } /// The exact and fixed mode implementation for Dragon. @@ -333,7 +333,7 @@ pub fn format_exact<'a>( *c = MaybeUninit::new(b'0'); } // SAFETY: we initialized that memory above. - return (unsafe { MaybeUninit::slice_assume_init_ref(&buf[..len]) }, k); + return (unsafe { buf[..len].assume_init_ref() }, k); } let mut d = 0; @@ -372,7 +372,7 @@ pub fn format_exact<'a>( // if rounding up changes the length, the exponent should also change. // but we've been requested a fixed number of digits, so do not alter the buffer... // SAFETY: we initialized that memory above. - if let Some(c) = round_up(unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..len]) }) { + if let Some(c) = round_up(unsafe { buf[..len].assume_init_mut() }) { // ...unless we've been requested the fixed precision instead. // we also need to check that, if the original buffer was empty, // the additional digit can only be added when `k == limit` (edge case). @@ -385,5 +385,5 @@ pub fn format_exact<'a>( } // SAFETY: we initialized that memory above. - (unsafe { MaybeUninit::slice_assume_init_ref(&buf[..len]) }, k) + (unsafe { buf[..len].assume_init_ref() }, k) } diff --git a/core/src/num/flt2dec/strategy/grisu.rs b/core/src/num/flt2dec/strategy/grisu.rs index bdf544a4133bb..2816de4c63339 100644 --- a/core/src/num/flt2dec/strategy/grisu.rs +++ b/core/src/num/flt2dec/strategy/grisu.rs @@ -275,7 +275,7 @@ pub fn format_shortest_opt<'a>( let ten_kappa = (ten_kappa as u64) << e; // scale 10^kappa back to the shared exponent return round_and_weed( // SAFETY: we initialized that memory above. - unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..i]) }, + unsafe { buf[..i].assume_init_mut() }, exp, plus1rem, delta1, @@ -324,7 +324,7 @@ pub fn format_shortest_opt<'a>( let ten_kappa = 1 << e; // implicit divisor return round_and_weed( // SAFETY: we initialized that memory above. - unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..i]) }, + unsafe { buf[..i].assume_init_mut() }, exp, r, threshold, @@ -713,7 +713,7 @@ pub fn format_exact_opt<'a>( // `10^kappa` did not overflow after all, the second check is fine. if ten_kappa - remainder > remainder && ten_kappa - 2 * remainder >= 2 * ulp { // SAFETY: our caller initialized that memory. - return Some((unsafe { MaybeUninit::slice_assume_init_ref(&buf[..len]) }, exp)); + return Some((unsafe { buf[..len].assume_init_ref() }, exp)); } // :<------- remainder ------>| : @@ -736,7 +736,7 @@ pub fn format_exact_opt<'a>( if remainder > ulp && ten_kappa - (remainder - ulp) <= remainder - ulp { if let Some(c) = // SAFETY: our caller must have initialized that memory. - round_up(unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..len]) }) + round_up(unsafe { buf[..len].assume_init_mut() }) { // only add an additional digit when we've been requested the fixed precision. // we also need to check that, if the original buffer was empty, @@ -748,7 +748,7 @@ pub fn format_exact_opt<'a>( } } // SAFETY: we and our caller initialized that memory. - return Some((unsafe { MaybeUninit::slice_assume_init_ref(&buf[..len]) }, exp)); + return Some((unsafe { buf[..len].assume_init_ref() }, exp)); } // otherwise we are doomed (i.e., some values between `v - 1 ulp` and `v + 1 ulp` are diff --git a/core/src/num/int_macros.rs b/core/src/num/int_macros.rs index 64dcb4c91e628..96a290ad5a09d 100644 --- a/core/src/num/int_macros.rs +++ b/core/src/num/int_macros.rs @@ -1152,7 +1152,6 @@ macro_rules! int_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_neg", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_neg(self) -> Self { @@ -1217,7 +1216,6 @@ macro_rules! int_impl { /// ``` #[stable(feature = "wrapping", since = "1.7.0")] #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1282,7 +1280,6 @@ macro_rules! int_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self { @@ -1340,7 +1337,6 @@ macro_rules! int_impl { /// ``` #[stable(feature = "wrapping", since = "1.7.0")] #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1405,7 +1401,6 @@ macro_rules! int_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self { @@ -1613,8 +1608,8 @@ macro_rules! int_impl { /// ``` #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".checked_isqrt(), Some(3));")] /// ``` - #[stable(feature = "isqrt", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "isqrt", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "isqrt", since = "1.84.0")] + #[rustc_const_stable(feature = "isqrt", since = "1.84.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1828,7 +1823,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -1986,7 +1981,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2014,7 +2009,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2042,7 +2037,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2069,7 +2064,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2134,7 +2129,6 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] pub const fn wrapping_shl(self, rhs: u32) -> Self { // SAFETY: the masking by the bitsize of the type ensures that we do not shift // out of bounds @@ -2164,7 +2158,6 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] pub const fn wrapping_shr(self, rhs: u32) -> Self { // SAFETY: the masking by the bitsize of the type ensures that we do not shift // out of bounds @@ -2519,6 +2512,114 @@ macro_rules! int_impl { (a as Self, b) } + /// Calculates the complete product `self * rhs` without the possibility to overflow. + /// + /// This returns the low-order (wrapping) bits and the high-order (overflow) bits + /// of the result as two separate values, in that order. + /// + /// If you also need to add a carry to the wide result, then you want + /// [`Self::carrying_mul`] instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// Please note that this example is shared between integer types. + /// Which explains why `i32` is used here. + /// + /// ``` + /// #![feature(bigint_helper_methods)] + /// assert_eq!(5i32.widening_mul(-2), (4294967286, -1)); + /// assert_eq!(1_000_000_000i32.widening_mul(-10), (2884901888, -3)); + /// ``` + #[unstable(feature = "bigint_helper_methods", issue = "85532")] + #[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn widening_mul(self, rhs: Self) -> ($UnsignedT, Self) { + Self::carrying_mul_add(self, rhs, 0, 0) + } + + /// Calculates the "full multiplication" `self * rhs + carry` + /// without the possibility to overflow. + /// + /// This returns the low-order (wrapping) bits and the high-order (overflow) bits + /// of the result as two separate values, in that order. + /// + /// Performs "long multiplication" which takes in an extra amount to add, and may return an + /// additional amount of overflow. This allows for chaining together multiple + /// multiplications to create "big integers" which represent larger values. + /// + /// If you don't need the `carry`, then you can use [`Self::widening_mul`] instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// Please note that this example is shared between integer types. + /// Which explains why `i32` is used here. + /// + /// ``` + /// #![feature(bigint_helper_methods)] + /// assert_eq!(5i32.carrying_mul(-2, 0), (4294967286, -1)); + /// assert_eq!(5i32.carrying_mul(-2, 10), (0, 0)); + /// assert_eq!(1_000_000_000i32.carrying_mul(-10, 0), (2884901888, -3)); + /// assert_eq!(1_000_000_000i32.carrying_mul(-10, 10), (2884901898, -3)); + #[doc = concat!("assert_eq!(", + stringify!($SelfT), "::MAX.carrying_mul(", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX), ", + "(", stringify!($SelfT), "::MAX.unsigned_abs() + 1, ", stringify!($SelfT), "::MAX / 2));" + )] + /// ``` + #[unstable(feature = "bigint_helper_methods", issue = "85532")] + #[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn carrying_mul(self, rhs: Self, carry: Self) -> ($UnsignedT, Self) { + Self::carrying_mul_add(self, rhs, carry, 0) + } + + /// Calculates the "full multiplication" `self * rhs + carry1 + carry2` + /// without the possibility to overflow. + /// + /// This returns the low-order (wrapping) bits and the high-order (overflow) bits + /// of the result as two separate values, in that order. + /// + /// Performs "long multiplication" which takes in an extra amount to add, and may return an + /// additional amount of overflow. This allows for chaining together multiple + /// multiplications to create "big integers" which represent larger values. + /// + /// If you don't need either `carry`, then you can use [`Self::widening_mul`] instead, + /// and if you only need one `carry`, then you can use [`Self::carrying_mul`] instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// Please note that this example is shared between integer types. + /// Which explains why `i32` is used here. + /// + /// ``` + /// #![feature(bigint_helper_methods)] + /// assert_eq!(5i32.carrying_mul_add(-2, 0, 0), (4294967286, -1)); + /// assert_eq!(5i32.carrying_mul_add(-2, 10, 10), (10, 0)); + /// assert_eq!(1_000_000_000i32.carrying_mul_add(-10, 0, 0), (2884901888, -3)); + /// assert_eq!(1_000_000_000i32.carrying_mul_add(-10, 10, 10), (2884901908, -3)); + #[doc = concat!("assert_eq!(", + stringify!($SelfT), "::MAX.carrying_mul_add(", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX), ", + "(", stringify!($UnsignedT), "::MAX, ", stringify!($SelfT), "::MAX / 2));" + )] + /// ``` + #[unstable(feature = "bigint_helper_methods", issue = "85532")] + #[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn carrying_mul_add(self, rhs: Self, carry: Self, add: Self) -> ($UnsignedT, Self) { + intrinsics::carrying_mul_add(self, rhs, carry, add) + } + /// Calculates the divisor when `self` is divided by `rhs`. /// /// Returns a tuple of the divisor along with a boolean indicating whether an arithmetic overflow would @@ -2526,7 +2627,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2557,7 +2658,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2588,7 +2689,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2619,7 +2720,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2860,8 +2961,8 @@ macro_rules! int_impl { /// ``` #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".isqrt(), 3);")] /// ``` - #[stable(feature = "isqrt", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "isqrt", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "isqrt", since = "1.84.0")] + #[rustc_const_stable(feature = "isqrt", since = "1.84.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2887,7 +2988,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0 or if `self` is `Self::MIN` + /// This function will panic if `rhs` is zero or if `self` is `Self::MIN` /// and `rhs` is -1. This behavior is not affected by the `overflow-checks` flag. /// /// # Examples @@ -2926,7 +3027,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0 or if `self` is `Self::MIN` and + /// This function will panic if `rhs` is zero or if `self` is `Self::MIN` and /// `rhs` is -1. This behavior is not affected by the `overflow-checks` flag. /// /// # Examples @@ -2975,7 +3076,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0 or if `self` is `Self::MIN` + /// This function will panic if `rhs` is zero or if `self` is `Self::MIN` /// and `rhs` is -1. This behavior is not affected by the `overflow-checks` flag. /// /// # Examples @@ -3019,7 +3120,7 @@ macro_rules! int_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0 or if `self` is `Self::MIN` + /// This function will panic if `rhs` is zero or if `self` is `Self::MIN` /// and `rhs` is -1. This behavior is not affected by the `overflow-checks` flag. /// /// # Examples diff --git a/core/src/num/mod.rs b/core/src/num/mod.rs index 9d9897b9cf05e..6c1b568e231d0 100644 --- a/core/src/num/mod.rs +++ b/core/src/num/mod.rs @@ -51,6 +51,10 @@ mod overflow_panic; mod saturating; mod wrapping; +/// 100% perma-unstable +#[doc(hidden)] +pub mod niche_types; + #[stable(feature = "rust1", since = "1.0.0")] #[cfg(not(no_fp_fmt_parse))] pub use dec2flt::ParseFloatError; @@ -77,6 +81,31 @@ pub use saturating::Saturating; #[stable(feature = "rust1", since = "1.0.0")] pub use wrapping::Wrapping; +macro_rules! u8_xe_bytes_doc { + () => { + " + +**Note**: This function is meaningless on `u8`. Byte order does not exist as a +concept for byte-sized integers. This function is only provided in symmetry +with larger integer types. + +" + }; +} + +macro_rules! i8_xe_bytes_doc { + () => { + " + +**Note**: This function is meaningless on `i8`. Byte order does not exist as a +concept for byte-sized integers. This function is only provided in symmetry +with larger integer types. You can cast from and to `u8` using `as i8` and `as +u8`. + +" + }; +} + macro_rules! usize_isize_to_xe_bytes_doc { () => { " @@ -103,18 +132,18 @@ macro_rules! midpoint_impl { ($SelfT:ty, unsigned) => { /// Calculates the middle point of `self` and `rhs`. /// - /// `midpoint(a, b)` is `(a + b) >> 1` as if it were performed in a - /// sufficiently-large signed integral type. This implies that the result is - /// always rounded towards negative infinity and that no overflow will ever occur. + /// `midpoint(a, b)` is `(a + b) / 2` as if it were performed in a + /// sufficiently-large unsigned integral type. This implies that the result is + /// always rounded towards zero and that no overflow will ever occur. /// /// # Examples /// /// ``` - /// #![feature(num_midpoint)] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")] #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".midpoint(4), 2);")] /// ``` - #[unstable(feature = "num_midpoint", issue = "110840")] + #[stable(feature = "num_midpoint", since = "1.85.0")] + #[rustc_const_stable(feature = "num_midpoint", since = "1.85.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -134,14 +163,14 @@ macro_rules! midpoint_impl { /// # Examples /// /// ``` - /// #![feature(num_midpoint)] + /// #![feature(num_midpoint_signed)] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")] #[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").midpoint(2), 0);")] #[doc = concat!("assert_eq!((-7", stringify!($SelfT), ").midpoint(0), -3);")] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(-7), -3);")] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(7), 3);")] /// ``` - #[unstable(feature = "num_midpoint", issue = "110840")] + #[unstable(feature = "num_midpoint_signed", issue = "110840")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -157,18 +186,18 @@ macro_rules! midpoint_impl { ($SelfT:ty, $WideT:ty, unsigned) => { /// Calculates the middle point of `self` and `rhs`. /// - /// `midpoint(a, b)` is `(a + b) >> 1` as if it were performed in a - /// sufficiently-large signed integral type. This implies that the result is - /// always rounded towards negative infinity and that no overflow will ever occur. + /// `midpoint(a, b)` is `(a + b) / 2` as if it were performed in a + /// sufficiently-large unsigned integral type. This implies that the result is + /// always rounded towards zero and that no overflow will ever occur. /// /// # Examples /// /// ``` - /// #![feature(num_midpoint)] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")] #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".midpoint(4), 2);")] /// ``` - #[unstable(feature = "num_midpoint", issue = "110840")] + #[stable(feature = "num_midpoint", since = "1.85.0")] + #[rustc_const_stable(feature = "num_midpoint", since = "1.85.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -186,14 +215,14 @@ macro_rules! midpoint_impl { /// # Examples /// /// ``` - /// #![feature(num_midpoint)] + /// #![feature(num_midpoint_signed)] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")] #[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").midpoint(2), 0);")] #[doc = concat!("assert_eq!((-7", stringify!($SelfT), ").midpoint(0), -3);")] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(-7), -3);")] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(7), 3);")] /// ``` - #[unstable(feature = "num_midpoint", issue = "110840")] + #[unstable(feature = "num_midpoint_signed", issue = "110840")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -203,134 +232,6 @@ macro_rules! midpoint_impl { }; } -macro_rules! widening_impl { - ($SelfT:ty, $WideT:ty, $BITS:literal, unsigned) => { - /// Calculates the complete product `self * rhs` without the possibility to overflow. - /// - /// This returns the low-order (wrapping) bits and the high-order (overflow) bits - /// of the result as two separate values, in that order. - /// - /// If you also need to add a carry to the wide result, then you want - /// [`Self::carrying_mul`] instead. - /// - /// # Examples - /// - /// Basic usage: - /// - /// Please note that this example is shared between integer types. - /// Which explains why `u32` is used here. - /// - /// ``` - /// #![feature(bigint_helper_methods)] - /// assert_eq!(5u32.widening_mul(2), (10, 0)); - /// assert_eq!(1_000_000_000u32.widening_mul(10), (1410065408, 2)); - /// ``` - #[unstable(feature = "bigint_helper_methods", issue = "85532")] - #[must_use = "this returns the result of the operation, \ - without modifying the original"] - #[inline] - pub const fn widening_mul(self, rhs: Self) -> (Self, Self) { - // note: longer-term this should be done via an intrinsic, - // but for now we can deal without an impl for u128/i128 - // SAFETY: overflow will be contained within the wider types - let wide = unsafe { (self as $WideT).unchecked_mul(rhs as $WideT) }; - (wide as $SelfT, (wide >> $BITS) as $SelfT) - } - - /// Calculates the "full multiplication" `self * rhs + carry` - /// without the possibility to overflow. - /// - /// This returns the low-order (wrapping) bits and the high-order (overflow) bits - /// of the result as two separate values, in that order. - /// - /// Performs "long multiplication" which takes in an extra amount to add, and may return an - /// additional amount of overflow. This allows for chaining together multiple - /// multiplications to create "big integers" which represent larger values. - /// - /// If you don't need the `carry`, then you can use [`Self::widening_mul`] instead. - /// - /// # Examples - /// - /// Basic usage: - /// - /// Please note that this example is shared between integer types. - /// Which explains why `u32` is used here. - /// - /// ``` - /// #![feature(bigint_helper_methods)] - /// assert_eq!(5u32.carrying_mul(2, 0), (10, 0)); - /// assert_eq!(5u32.carrying_mul(2, 10), (20, 0)); - /// assert_eq!(1_000_000_000u32.carrying_mul(10, 0), (1410065408, 2)); - /// assert_eq!(1_000_000_000u32.carrying_mul(10, 10), (1410065418, 2)); - #[doc = concat!("assert_eq!(", - stringify!($SelfT), "::MAX.carrying_mul(", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX), ", - "(0, ", stringify!($SelfT), "::MAX));" - )] - /// ``` - /// - /// This is the core operation needed for scalar multiplication when - /// implementing it for wider-than-native types. - /// - /// ``` - /// #![feature(bigint_helper_methods)] - /// fn scalar_mul_eq(little_endian_digits: &mut Vec, multiplicand: u16) { - /// let mut carry = 0; - /// for d in little_endian_digits.iter_mut() { - /// (*d, carry) = d.carrying_mul(multiplicand, carry); - /// } - /// if carry != 0 { - /// little_endian_digits.push(carry); - /// } - /// } - /// - /// let mut v = vec![10, 20]; - /// scalar_mul_eq(&mut v, 3); - /// assert_eq!(v, [30, 60]); - /// - /// assert_eq!(0x87654321_u64 * 0xFEED, 0x86D3D159E38D); - /// let mut v = vec![0x4321, 0x8765]; - /// scalar_mul_eq(&mut v, 0xFEED); - /// assert_eq!(v, [0xE38D, 0xD159, 0x86D3]); - /// ``` - /// - /// If `carry` is zero, this is similar to [`overflowing_mul`](Self::overflowing_mul), - /// except that it gives the value of the overflow instead of just whether one happened: - /// - /// ``` - /// #![feature(bigint_helper_methods)] - /// let r = u8::carrying_mul(7, 13, 0); - /// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(7, 13)); - /// let r = u8::carrying_mul(13, 42, 0); - /// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(13, 42)); - /// ``` - /// - /// The value of the first field in the returned tuple matches what you'd get - /// by combining the [`wrapping_mul`](Self::wrapping_mul) and - /// [`wrapping_add`](Self::wrapping_add) methods: - /// - /// ``` - /// #![feature(bigint_helper_methods)] - /// assert_eq!( - /// 789_u16.carrying_mul(456, 123).0, - /// 789_u16.wrapping_mul(456).wrapping_add(123), - /// ); - /// ``` - #[unstable(feature = "bigint_helper_methods", issue = "85532")] - #[must_use = "this returns the result of the operation, \ - without modifying the original"] - #[inline] - pub const fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self) { - // note: longer-term this should be done via an intrinsic, - // but for now we can deal without an impl for u128/i128 - // SAFETY: overflow will be contained within the wider types - let wide = unsafe { - (self as $WideT).unchecked_mul(rhs as $WideT).unchecked_add(carry as $WideT) - }; - (wide as $SelfT, (wide >> $BITS) as $SelfT) - } - }; -} - impl i8 { int_impl! { Self = i8, @@ -348,8 +249,8 @@ impl i8 { reversed = "0x48", le_bytes = "[0x12]", be_bytes = "[0x12]", - to_xe_bytes_doc = "", - from_xe_bytes_doc = "", + to_xe_bytes_doc = i8_xe_bytes_doc!(), + from_xe_bytes_doc = i8_xe_bytes_doc!(), bound_condition = "", } midpoint_impl! { i8, i16, signed } @@ -547,11 +448,10 @@ impl u8 { reversed = "0x48", le_bytes = "[0x12]", be_bytes = "[0x12]", - to_xe_bytes_doc = "", - from_xe_bytes_doc = "", + to_xe_bytes_doc = u8_xe_bytes_doc!(), + from_xe_bytes_doc = u8_xe_bytes_doc!(), bound_condition = "", } - widening_impl! { u8, u16, 8, unsigned } midpoint_impl! { u8, u16, unsigned } /// Checks if the value is within the ASCII range. @@ -677,7 +577,7 @@ impl u8 { /// /// [`to_ascii_uppercase`]: Self::to_ascii_uppercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")] #[inline] pub const fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); @@ -703,7 +603,7 @@ impl u8 { /// /// [`to_ascii_lowercase`]: Self::to_ascii_lowercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")] #[inline] pub const fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); @@ -1167,7 +1067,6 @@ impl u16 { from_xe_bytes_doc = "", bound_condition = "", } - widening_impl! { u16, u32, 16, unsigned } midpoint_impl! { u16, u32, unsigned } /// Checks if the value is a Unicode surrogate code point, which are disallowed values for [`char`]. @@ -1215,7 +1114,6 @@ impl u32 { from_xe_bytes_doc = "", bound_condition = "", } - widening_impl! { u32, u64, 32, unsigned } midpoint_impl! { u32, u64, unsigned } } @@ -1239,7 +1137,6 @@ impl u64 { from_xe_bytes_doc = "", bound_condition = "", } - widening_impl! { u64, u128, 64, unsigned } midpoint_impl! { u64, u128, unsigned } } @@ -1289,7 +1186,6 @@ impl usize { from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(), bound_condition = " on 16-bit targets", } - widening_impl! { usize, u32, 16, unsigned } midpoint_impl! { usize, u32, unsigned } } @@ -1314,7 +1210,6 @@ impl usize { from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(), bound_condition = " on 32-bit targets", } - widening_impl! { usize, u64, 32, unsigned } midpoint_impl! { usize, u64, unsigned } } @@ -1339,7 +1234,6 @@ impl usize { from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(), bound_condition = " on 64-bit targets", } - widening_impl! { usize, u128, 64, unsigned } midpoint_impl! { usize, u128, unsigned } } @@ -1449,7 +1343,6 @@ from_str_radix_int_impl! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 } #[doc(hidden)] #[inline(always)] #[unstable(issue = "none", feature = "std_internals")] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_from_str", since = "1.82.0"))] pub const fn can_not_overflow(radix: u32, is_signed_ty: bool, digits: &[u8]) -> bool { radix <= 16 && digits.len() <= mem::size_of::() * 2 - is_signed_ty as usize } diff --git a/core/src/num/niche_types.rs b/core/src/num/niche_types.rs new file mode 100644 index 0000000000000..096713c318f8d --- /dev/null +++ b/core/src/num/niche_types.rs @@ -0,0 +1,168 @@ +#![unstable( + feature = "temporary_niche_types", + issue = "none", + reason = "for core, alloc, and std internals until pattern types are further along" +)] + +use crate::cmp::Ordering; +use crate::fmt; +use crate::hash::{Hash, Hasher}; +use crate::marker::StructuralPartialEq; + +macro_rules! define_valid_range_type { + ($( + $(#[$m:meta])* + $vis:vis struct $name:ident($int:ident as $uint:ident in $low:literal..=$high:literal); + )+) => {$( + #[derive(Clone, Copy, Eq)] + #[repr(transparent)] + #[rustc_layout_scalar_valid_range_start($low)] + #[rustc_layout_scalar_valid_range_end($high)] + $(#[$m])* + $vis struct $name($int); + + const _: () = { + // With the `valid_range` attributes, it's always specified as unsigned + assert!(<$uint>::MIN == 0); + let ulow: $uint = $low; + let uhigh: $uint = $high; + assert!(ulow <= uhigh); + + assert!(size_of::<$int>() == size_of::<$uint>()); + }; + + impl $name { + /// Constructs an instance of this type from the underlying integer + /// primitive without checking whether its zero. + /// + /// # Safety + /// Immediate language UB if `val == 0`, as it violates the validity + /// invariant of this type. + #[inline] + pub const unsafe fn new_unchecked(val: $int) -> Self { + // SAFETY: Caller promised that `val` is non-zero. + unsafe { $name(val) } + } + + #[inline] + pub const fn as_inner(self) -> $int { + // SAFETY: This is a transparent wrapper, so unwrapping it is sound + // (Not using `.0` due to MCP#807.) + unsafe { crate::mem::transmute(self) } + } + } + + // This is required to allow matching a constant. We don't get it from a derive + // because the derived `PartialEq` would do a field projection, which is banned + // by . + impl StructuralPartialEq for $name {} + + impl PartialEq for $name { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.as_inner() == other.as_inner() + } + } + + impl Ord for $name { + #[inline] + fn cmp(&self, other: &Self) -> Ordering { + Ord::cmp(&self.as_inner(), &other.as_inner()) + } + } + + impl PartialOrd for $name { + #[inline] + fn partial_cmp(&self, other: &Self) -> Option { + Some(Ord::cmp(self, other)) + } + } + + impl Hash for $name { + // Required method + fn hash(&self, state: &mut H) { + Hash::hash(&self.as_inner(), state); + } + } + + impl fmt::Debug for $name { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + <$int as fmt::Debug>::fmt(&self.as_inner(), f) + } + } + )+}; +} + +define_valid_range_type! { + pub struct Nanoseconds(u32 as u32 in 0..=999_999_999); +} + +impl Nanoseconds { + // SAFETY: 0 is within the valid range + pub const ZERO: Self = unsafe { Nanoseconds::new_unchecked(0) }; +} + +impl Default for Nanoseconds { + #[inline] + fn default() -> Self { + Self::ZERO + } +} + +define_valid_range_type! { + pub struct NonZeroU8Inner(u8 as u8 in 1..=0xff); + pub struct NonZeroU16Inner(u16 as u16 in 1..=0xff_ff); + pub struct NonZeroU32Inner(u32 as u32 in 1..=0xffff_ffff); + pub struct NonZeroU64Inner(u64 as u64 in 1..=0xffffffff_ffffffff); + pub struct NonZeroU128Inner(u128 as u128 in 1..=0xffffffffffffffff_ffffffffffffffff); + + pub struct NonZeroI8Inner(i8 as u8 in 1..=0xff); + pub struct NonZeroI16Inner(i16 as u16 in 1..=0xff_ff); + pub struct NonZeroI32Inner(i32 as u32 in 1..=0xffff_ffff); + pub struct NonZeroI64Inner(i64 as u64 in 1..=0xffffffff_ffffffff); + pub struct NonZeroI128Inner(i128 as u128 in 1..=0xffffffffffffffff_ffffffffffffffff); +} + +#[cfg(target_pointer_width = "16")] +define_valid_range_type! { + pub struct UsizeNoHighBit(usize as usize in 0..=0x7fff); + pub struct NonZeroUsizeInner(usize as usize in 1..=0xffff); + pub struct NonZeroIsizeInner(isize as usize in 1..=0xffff); +} +#[cfg(target_pointer_width = "32")] +define_valid_range_type! { + pub struct UsizeNoHighBit(usize as usize in 0..=0x7fff_ffff); + pub struct NonZeroUsizeInner(usize as usize in 1..=0xffff_ffff); + pub struct NonZeroIsizeInner(isize as usize in 1..=0xffff_ffff); +} +#[cfg(target_pointer_width = "64")] +define_valid_range_type! { + pub struct UsizeNoHighBit(usize as usize in 0..=0x7fff_ffff_ffff_ffff); + pub struct NonZeroUsizeInner(usize as usize in 1..=0xffff_ffff_ffff_ffff); + pub struct NonZeroIsizeInner(isize as usize in 1..=0xffff_ffff_ffff_ffff); +} + +define_valid_range_type! { + pub struct U32NotAllOnes(u32 as u32 in 0..=0xffff_fffe); + pub struct I32NotAllOnes(i32 as u32 in 0..=0xffff_fffe); + + pub struct U64NotAllOnes(u64 as u64 in 0..=0xffff_ffff_ffff_fffe); + pub struct I64NotAllOnes(i64 as u64 in 0..=0xffff_ffff_ffff_fffe); +} + +pub trait NotAllOnesHelper { + type Type; +} +pub type NotAllOnes = ::Type; +impl NotAllOnesHelper for u32 { + type Type = U32NotAllOnes; +} +impl NotAllOnesHelper for i32 { + type Type = I32NotAllOnes; +} +impl NotAllOnesHelper for u64 { + type Type = U64NotAllOnes; +} +impl NotAllOnesHelper for i64 { + type Type = I64NotAllOnes; +} diff --git a/core/src/num/nonzero.rs b/core/src/num/nonzero.rs index b883a0c2ec7f9..dbce64420ac45 100644 --- a/core/src/num/nonzero.rs +++ b/core/src/num/nonzero.rs @@ -43,19 +43,6 @@ macro_rules! impl_zeroable_primitive { issue = "none" )] pub trait Sealed {} - - $( - #[derive(Debug, Clone, Copy, PartialEq)] - #[repr(transparent)] - #[rustc_layout_scalar_valid_range_start(1)] - #[rustc_nonnull_optimization_guaranteed] - #[unstable( - feature = "nonzero_internals", - reason = "implementation detail which may disappear or be replaced at any time", - issue = "none" - )] - pub struct $NonZeroInner($primitive); - )+ } $( @@ -72,7 +59,7 @@ macro_rules! impl_zeroable_primitive { issue = "none" )] unsafe impl ZeroablePrimitive for $primitive { - type NonZeroInner = private::$NonZeroInner; + type NonZeroInner = super::niche_types::$NonZeroInner; } )+ }; @@ -139,9 +126,9 @@ impl_nonzero_fmt! { LowerHex #[stable(feature = "nonzero", since = "1.28.0")] UpperHex - #[stable(feature = "nonzero_fmt_exp", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "nonzero_fmt_exp", since = "1.84.0")] LowerExp - #[stable(feature = "nonzero_fmt_exp", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "nonzero_fmt_exp", since = "1.84.0")] UpperExp } @@ -172,7 +159,7 @@ where { #[inline] fn clone(&self) -> Self { - Self(self.0) + *self } } @@ -440,15 +427,21 @@ where #[rustc_const_stable(feature = "const_nonzero_get", since = "1.34.0")] #[inline] pub const fn get(self) -> T { - // FIXME: This can be changed to simply `self.0` once LLVM supports `!range` metadata - // for function arguments: https://github.com/llvm/llvm-project/issues/76628 - // // Rustc can set range metadata only if it loads `self` from // memory somewhere. If the value of `self` was from by-value argument // of some not-inlined function, LLVM don't have range metadata // to understand that the value cannot be zero. // - // For now, using the transmute `assume`s the range at runtime. + // Using the transmute `assume`s the range at runtime. + // + // Even once LLVM supports `!range` metadata for function arguments + // (see ), this can't + // be `.0` because MCP#807 bans field-projecting into `scalar_valid_range` + // types, and it arguably wouldn't want to be anyway because if this is + // MIR-inlined, there's no opportunity to put that argument metadata anywhere. + // + // The good answer here will eventually be pattern types, which will hopefully + // allow it to go back to `.0`, maybe with a cast of some sort. // // SAFETY: `ZeroablePrimitive` guarantees that the size and bit validity // of `.0` is such that this transmute is sound. @@ -614,7 +607,6 @@ macro_rules! nonzero_integer { /// ``` /// #[unstable(feature = "non_zero_count_ones", issue = "120287")] - #[rustc_const_unstable(feature = "non_zero_count_ones", issue = "120287")] #[doc(alias = "popcount")] #[doc(alias = "popcnt")] #[must_use = "this returns the result of the operation, \ @@ -1509,8 +1501,6 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Examples /// /// ``` - /// #![feature(num_midpoint)] - /// /// # use std::num::NonZero; /// # /// # fn main() { test().unwrap(); } @@ -1524,7 +1514,8 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Some(()) /// # } /// ``` - #[unstable(feature = "num_midpoint", issue = "110840")] + #[stable(feature = "num_midpoint", since = "1.85.0")] + #[rustc_const_stable(feature = "num_midpoint", since = "1.85.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1587,8 +1578,8 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// # Some(()) /// # } /// ``` - #[stable(feature = "isqrt", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "isqrt", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "isqrt", since = "1.84.0")] + #[rustc_const_stable(feature = "isqrt", since = "1.84.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/core/src/num/uint_macros.rs b/core/src/num/uint_macros.rs index 0383c13fa082d..404e4bcffd379 100644 --- a/core/src/num/uint_macros.rs +++ b/core/src/num/uint_macros.rs @@ -4,7 +4,7 @@ macro_rules! uint_impl { ActualT = $ActualT:ident, SignedT = $SignedT:ident, - // There are all for use *only* in doc comments. + // These are all for use *only* in doc comments. // As such, they're all passed as literals -- passing them as a string // literal is fine if they need to be multiple code tokens. // In non-comments, use the associated constants rather than these. @@ -1434,7 +1434,6 @@ macro_rules! uint_impl { /// ``` #[stable(feature = "wrapping", since = "1.7.0")] #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1499,7 +1498,6 @@ macro_rules! uint_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self { @@ -1557,7 +1555,6 @@ macro_rules! uint_impl { /// ``` #[stable(feature = "wrapping", since = "1.7.0")] #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1622,7 +1619,6 @@ macro_rules! uint_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self { @@ -1877,7 +1873,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2034,7 +2030,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2063,7 +2059,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2091,7 +2087,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2121,7 +2117,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2193,7 +2189,6 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] pub const fn wrapping_shl(self, rhs: u32) -> Self { // SAFETY: the masking by the bitsize of the type ensures that we do not shift // out of bounds @@ -2226,7 +2221,6 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] pub const fn wrapping_shr(self, rhs: u32) -> Self { // SAFETY: the masking by the bitsize of the type ensures that we do not shift // out of bounds @@ -2360,7 +2354,7 @@ macro_rules! uint_impl { // to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic let (a, b) = self.overflowing_add(rhs); let (c, d) = a.overflowing_add(carry as $SelfT); - (c, b || d) + (c, b | d) } /// Calculates `self` + `rhs` with a signed `rhs`. @@ -2451,7 +2445,7 @@ macro_rules! uint_impl { // to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic let (a, b) = self.overflowing_sub(rhs); let (c, d) = a.overflowing_sub(borrow as $SelfT); - (c, b || d) + (c, b | d) } /// Calculates `self` - `rhs` with a signed `rhs` @@ -2536,6 +2530,162 @@ macro_rules! uint_impl { (a as Self, b) } + /// Calculates the complete product `self * rhs` without the possibility to overflow. + /// + /// This returns the low-order (wrapping) bits and the high-order (overflow) bits + /// of the result as two separate values, in that order. + /// + /// If you also need to add a carry to the wide result, then you want + /// [`Self::carrying_mul`] instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// Please note that this example is shared between integer types. + /// Which explains why `u32` is used here. + /// + /// ``` + /// #![feature(bigint_helper_methods)] + /// assert_eq!(5u32.widening_mul(2), (10, 0)); + /// assert_eq!(1_000_000_000u32.widening_mul(10), (1410065408, 2)); + /// ``` + #[unstable(feature = "bigint_helper_methods", issue = "85532")] + #[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn widening_mul(self, rhs: Self) -> (Self, Self) { + Self::carrying_mul_add(self, rhs, 0, 0) + } + + /// Calculates the "full multiplication" `self * rhs + carry` + /// without the possibility to overflow. + /// + /// This returns the low-order (wrapping) bits and the high-order (overflow) bits + /// of the result as two separate values, in that order. + /// + /// Performs "long multiplication" which takes in an extra amount to add, and may return an + /// additional amount of overflow. This allows for chaining together multiple + /// multiplications to create "big integers" which represent larger values. + /// + /// If you don't need the `carry`, then you can use [`Self::widening_mul`] instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// Please note that this example is shared between integer types. + /// Which explains why `u32` is used here. + /// + /// ``` + /// #![feature(bigint_helper_methods)] + /// assert_eq!(5u32.carrying_mul(2, 0), (10, 0)); + /// assert_eq!(5u32.carrying_mul(2, 10), (20, 0)); + /// assert_eq!(1_000_000_000u32.carrying_mul(10, 0), (1410065408, 2)); + /// assert_eq!(1_000_000_000u32.carrying_mul(10, 10), (1410065418, 2)); + #[doc = concat!("assert_eq!(", + stringify!($SelfT), "::MAX.carrying_mul(", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX), ", + "(0, ", stringify!($SelfT), "::MAX));" + )] + /// ``` + /// + /// This is the core operation needed for scalar multiplication when + /// implementing it for wider-than-native types. + /// + /// ``` + /// #![feature(bigint_helper_methods)] + /// fn scalar_mul_eq(little_endian_digits: &mut Vec, multiplicand: u16) { + /// let mut carry = 0; + /// for d in little_endian_digits.iter_mut() { + /// (*d, carry) = d.carrying_mul(multiplicand, carry); + /// } + /// if carry != 0 { + /// little_endian_digits.push(carry); + /// } + /// } + /// + /// let mut v = vec![10, 20]; + /// scalar_mul_eq(&mut v, 3); + /// assert_eq!(v, [30, 60]); + /// + /// assert_eq!(0x87654321_u64 * 0xFEED, 0x86D3D159E38D); + /// let mut v = vec![0x4321, 0x8765]; + /// scalar_mul_eq(&mut v, 0xFEED); + /// assert_eq!(v, [0xE38D, 0xD159, 0x86D3]); + /// ``` + /// + /// If `carry` is zero, this is similar to [`overflowing_mul`](Self::overflowing_mul), + /// except that it gives the value of the overflow instead of just whether one happened: + /// + /// ``` + /// #![feature(bigint_helper_methods)] + /// let r = u8::carrying_mul(7, 13, 0); + /// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(7, 13)); + /// let r = u8::carrying_mul(13, 42, 0); + /// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(13, 42)); + /// ``` + /// + /// The value of the first field in the returned tuple matches what you'd get + /// by combining the [`wrapping_mul`](Self::wrapping_mul) and + /// [`wrapping_add`](Self::wrapping_add) methods: + /// + /// ``` + /// #![feature(bigint_helper_methods)] + /// assert_eq!( + /// 789_u16.carrying_mul(456, 123).0, + /// 789_u16.wrapping_mul(456).wrapping_add(123), + /// ); + /// ``` + #[unstable(feature = "bigint_helper_methods", issue = "85532")] + #[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self) { + Self::carrying_mul_add(self, rhs, carry, 0) + } + + /// Calculates the "full multiplication" `self * rhs + carry1 + carry2` + /// without the possibility to overflow. + /// + /// This returns the low-order (wrapping) bits and the high-order (overflow) bits + /// of the result as two separate values, in that order. + /// + /// Performs "long multiplication" which takes in an extra amount to add, and may return an + /// additional amount of overflow. This allows for chaining together multiple + /// multiplications to create "big integers" which represent larger values. + /// + /// If you don't need either `carry`, then you can use [`Self::widening_mul`] instead, + /// and if you only need one `carry`, then you can use [`Self::carrying_mul`] instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// Please note that this example is shared between integer types. + /// Which explains why `u32` is used here. + /// + /// ``` + /// #![feature(bigint_helper_methods)] + /// assert_eq!(5u32.carrying_mul_add(2, 0, 0), (10, 0)); + /// assert_eq!(5u32.carrying_mul_add(2, 10, 10), (30, 0)); + /// assert_eq!(1_000_000_000u32.carrying_mul_add(10, 0, 0), (1410065408, 2)); + /// assert_eq!(1_000_000_000u32.carrying_mul_add(10, 10, 10), (1410065428, 2)); + #[doc = concat!("assert_eq!(", + stringify!($SelfT), "::MAX.carrying_mul_add(", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX), ", + "(", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX));" + )] + /// ``` + #[unstable(feature = "bigint_helper_methods", issue = "85532")] + #[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn carrying_mul_add(self, rhs: Self, carry: Self, add: Self) -> (Self, Self) { + intrinsics::carrying_mul_add(self, rhs, carry, add) + } + /// Calculates the divisor when `self` is divided by `rhs`. /// /// Returns a tuple of the divisor along with a boolean indicating @@ -2545,7 +2695,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2576,7 +2726,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2604,7 +2754,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2635,7 +2785,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2838,8 +2988,8 @@ macro_rules! uint_impl { /// ``` #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".isqrt(), 3);")] /// ``` - #[stable(feature = "isqrt", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "isqrt", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "isqrt", since = "1.84.0")] + #[rustc_const_stable(feature = "isqrt", since = "1.84.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2872,7 +3022,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -2900,7 +3050,7 @@ macro_rules! uint_impl { /// /// # Panics /// - /// This function will panic if `rhs` is 0. + /// This function will panic if `rhs` is zero. /// /// # Examples /// @@ -3091,7 +3241,6 @@ macro_rules! uint_impl { // overflow cases it instead ends up returning the maximum value // of the type, and can return 0 for 0. #[inline] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_pow", since = "1.50.0"))] const fn one_less_than_next_power_of_two(self) -> Self { if self <= 1 { return 0; } @@ -3169,7 +3318,6 @@ macro_rules! uint_impl { #[inline] #[unstable(feature = "wrapping_next_power_of_two", issue = "32463", reason = "needs decision on wrapping behavior")] - #[rustc_const_unstable(feature = "wrapping_next_power_of_two", issue = "32463")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn wrapping_next_power_of_two(self) -> Self { diff --git a/core/src/ops/arith.rs b/core/src/ops/arith.rs index 565bccf589826..fe7ff2d9ede6a 100644 --- a/core/src/ops/arith.rs +++ b/core/src/ops/arith.rs @@ -65,6 +65,7 @@ /// ``` #[lang = "add"] #[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature = "const_ops", issue = "90080")] #[rustc_on_unimplemented( on(all(_Self = "{integer}", Rhs = "{float}"), message = "cannot add a float to an integer",), on(all(_Self = "{float}", Rhs = "{integer}"), message = "cannot add an integer to a float",), @@ -73,7 +74,7 @@ append_const_msg )] #[doc(alias = "+")] -#[cfg_attr(not(bootstrap), const_trait)] +#[const_trait] pub trait Add { /// The resulting type after applying the `+` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -95,18 +96,6 @@ pub trait Add { macro_rules! add_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[cfg(bootstrap)] - impl Add for $t { - type Output = $t; - - #[inline] - #[track_caller] - #[rustc_inherit_overflow_checks] - fn add(self, other: $t) -> $t { self + other } - } - - #[stable(feature = "rust1", since = "1.0.0")] - #[cfg(not(bootstrap))] impl const Add for $t { type Output = $t; diff --git a/core/src/ops/async_function.rs b/core/src/ops/async_function.rs index 4b230b15a1e6f..c90ae7babbd93 100644 --- a/core/src/ops/async_function.rs +++ b/core/src/ops/async_function.rs @@ -4,7 +4,7 @@ use crate::marker::Tuple; /// An async-aware version of the [`Fn`](crate::ops::Fn) trait. /// /// All `async fn` and functions returning futures implement this trait. -#[unstable(feature = "async_closure", issue = "62290")] +#[stable(feature = "async_closure", since = "1.85.0")] #[rustc_paren_sugar] #[fundamental] #[must_use = "async closures are lazy and do nothing unless called"] @@ -18,7 +18,7 @@ pub trait AsyncFn: AsyncFnMut { /// An async-aware version of the [`FnMut`](crate::ops::FnMut) trait. /// /// All `async fn` and functions returning futures implement this trait. -#[unstable(feature = "async_closure", issue = "62290")] +#[stable(feature = "async_closure", since = "1.85.0")] #[rustc_paren_sugar] #[fundamental] #[must_use = "async closures are lazy and do nothing unless called"] @@ -39,7 +39,7 @@ pub trait AsyncFnMut: AsyncFnOnce { /// An async-aware version of the [`FnOnce`](crate::ops::FnOnce) trait. /// /// All `async fn` and functions returning futures implement this trait. -#[unstable(feature = "async_closure", issue = "62290")] +#[stable(feature = "async_closure", since = "1.85.0")] #[rustc_paren_sugar] #[fundamental] #[must_use = "async closures are lazy and do nothing unless called"] @@ -64,7 +64,7 @@ mod impls { use super::{AsyncFn, AsyncFnMut, AsyncFnOnce}; use crate::marker::Tuple; - #[unstable(feature = "async_fn_traits", issue = "none")] + #[stable(feature = "async_closure", since = "1.85.0")] impl AsyncFn for &F where F: AsyncFn, @@ -74,7 +74,7 @@ mod impls { } } - #[unstable(feature = "async_fn_traits", issue = "none")] + #[stable(feature = "async_closure", since = "1.85.0")] impl AsyncFnMut for &F where F: AsyncFn, @@ -89,7 +89,7 @@ mod impls { } } - #[unstable(feature = "async_fn_traits", issue = "none")] + #[stable(feature = "async_closure", since = "1.85.0")] impl<'a, A: Tuple, F: ?Sized> AsyncFnOnce for &'a F where F: AsyncFn, @@ -102,7 +102,7 @@ mod impls { } } - #[unstable(feature = "async_fn_traits", issue = "none")] + #[stable(feature = "async_closure", since = "1.85.0")] impl AsyncFnMut for &mut F where F: AsyncFnMut, @@ -117,7 +117,7 @@ mod impls { } } - #[unstable(feature = "async_fn_traits", issue = "none")] + #[stable(feature = "async_closure", since = "1.85.0")] impl<'a, A: Tuple, F: ?Sized> AsyncFnOnce for &'a mut F where F: AsyncFnMut, diff --git a/core/src/ops/control_flow.rs b/core/src/ops/control_flow.rs index 55deabbee8fb5..c8fcee5c140f5 100644 --- a/core/src/ops/control_flow.rs +++ b/core/src/ops/control_flow.rs @@ -79,6 +79,7 @@ use crate::{convert, ops}; /// [`Break`]: ControlFlow::Break /// [`Continue`]: ControlFlow::Continue #[stable(feature = "control_flow_enum_type", since = "1.55.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "ControlFlow")] // ControlFlow should not implement PartialOrd or Ord, per RFC 3058: // https://rust-lang.github.io/rfcs/3058-try-trait-v2.html#traits-for-controlflow #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -140,8 +141,8 @@ impl ControlFlow { /// ``` /// use std::ops::ControlFlow; /// - /// assert!(ControlFlow::::Break(3).is_break()); - /// assert!(!ControlFlow::::Continue(3).is_break()); + /// assert!(ControlFlow::<&str, i32>::Break("Stop right there!").is_break()); + /// assert!(!ControlFlow::<&str, i32>::Continue(3).is_break()); /// ``` #[inline] #[stable(feature = "control_flow_enum_is", since = "1.59.0")] @@ -156,8 +157,8 @@ impl ControlFlow { /// ``` /// use std::ops::ControlFlow; /// - /// assert!(!ControlFlow::::Break(3).is_continue()); - /// assert!(ControlFlow::::Continue(3).is_continue()); + /// assert!(!ControlFlow::<&str, i32>::Break("Stop right there!").is_continue()); + /// assert!(ControlFlow::<&str, i32>::Continue(3).is_continue()); /// ``` #[inline] #[stable(feature = "control_flow_enum_is", since = "1.59.0")] @@ -173,8 +174,8 @@ impl ControlFlow { /// ``` /// use std::ops::ControlFlow; /// - /// assert_eq!(ControlFlow::::Break(3).break_value(), Some(3)); - /// assert_eq!(ControlFlow::::Continue(3).break_value(), None); + /// assert_eq!(ControlFlow::<&str, i32>::Break("Stop right there!").break_value(), Some("Stop right there!")); + /// assert_eq!(ControlFlow::<&str, i32>::Continue(3).break_value(), None); /// ``` #[inline] #[stable(feature = "control_flow_enum", since = "1.83.0")] @@ -204,8 +205,8 @@ impl ControlFlow { /// ``` /// use std::ops::ControlFlow; /// - /// assert_eq!(ControlFlow::::Break(3).continue_value(), None); - /// assert_eq!(ControlFlow::::Continue(3).continue_value(), Some(3)); + /// assert_eq!(ControlFlow::<&str, i32>::Break("Stop right there!").continue_value(), None); + /// assert_eq!(ControlFlow::<&str, i32>::Continue(3).continue_value(), Some(3)); /// ``` #[inline] #[stable(feature = "control_flow_enum", since = "1.83.0")] diff --git a/core/src/ops/deref.rs b/core/src/ops/deref.rs index e9bb40d0fdd17..11490ea2bfcb4 100644 --- a/core/src/ops/deref.rs +++ b/core/src/ops/deref.rs @@ -133,7 +133,8 @@ #[doc(alias = "&*")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Deref"] -#[cfg_attr(not(bootstrap), const_trait)] +#[const_trait] +#[rustc_const_unstable(feature = "const_deref", issue = "88955")] pub trait Deref { /// The resulting type after dereferencing. #[stable(feature = "rust1", since = "1.0.0")] @@ -148,18 +149,6 @@ pub trait Deref { fn deref(&self) -> &Self::Target; } -#[cfg(bootstrap)] -#[stable(feature = "rust1", since = "1.0.0")] -impl Deref for &T { - type Target = T; - - #[rustc_diagnostic_item = "noop_method_deref"] - fn deref(&self) -> &T { - *self - } -} - -#[cfg(not(bootstrap))] #[stable(feature = "rust1", since = "1.0.0")] impl const Deref for &T { type Target = T; @@ -173,17 +162,6 @@ impl const Deref for &T { #[stable(feature = "rust1", since = "1.0.0")] impl !DerefMut for &T {} -#[cfg(bootstrap)] -#[stable(feature = "rust1", since = "1.0.0")] -impl Deref for &mut T { - type Target = T; - - fn deref(&self) -> &T { - *self - } -} - -#[cfg(not(bootstrap))] #[stable(feature = "rust1", since = "1.0.0")] impl const Deref for &mut T { type Target = T; @@ -282,11 +260,11 @@ impl const Deref for &mut T { /// *x = 'b'; /// assert_eq!('b', x.value); /// ``` -#[cfg(not(bootstrap))] #[lang = "deref_mut"] #[doc(alias = "*")] #[stable(feature = "rust1", since = "1.0.0")] #[const_trait] +#[rustc_const_unstable(feature = "const_deref", issue = "88955")] pub trait DerefMut: ~const Deref { /// Mutably dereferences the value. #[stable(feature = "rust1", since = "1.0.0")] @@ -294,27 +272,6 @@ pub trait DerefMut: ~const Deref { fn deref_mut(&mut self) -> &mut Self::Target; } -/// Bootstrap -#[lang = "deref_mut"] -#[doc(alias = "*")] -#[stable(feature = "rust1", since = "1.0.0")] -#[cfg(bootstrap)] -pub trait DerefMut: Deref { - /// Mutably dereferences the value. - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_diagnostic_item = "deref_mut_method"] - fn deref_mut(&mut self) -> &mut Self::Target; -} - -#[cfg(bootstrap)] -#[stable(feature = "rust1", since = "1.0.0")] -impl DerefMut for &mut T { - fn deref_mut(&mut self) -> &mut T { - *self - } -} - -#[cfg(not(bootstrap))] #[stable(feature = "rust1", since = "1.0.0")] impl const DerefMut for &mut T { fn deref_mut(&mut self) -> &mut T { @@ -405,18 +362,15 @@ unsafe impl DerefPure for &mut T {} /// } /// ``` #[lang = "receiver"] -#[cfg(not(bootstrap))] #[unstable(feature = "arbitrary_self_types", issue = "44874")] pub trait Receiver { /// The target type on which the method may be called. - #[cfg(not(bootstrap))] #[rustc_diagnostic_item = "receiver_target"] #[lang = "receiver_target"] #[unstable(feature = "arbitrary_self_types", issue = "44874")] type Target: ?Sized; } -#[cfg(not(bootstrap))] #[unstable(feature = "arbitrary_self_types", issue = "44874")] impl Receiver for P where @@ -433,8 +387,7 @@ where /// facility based around the current "arbitrary self types" unstable feature. /// That new facility will use the replacement trait above called `Receiver` /// which is why this is now named `LegacyReceiver`. -#[cfg_attr(bootstrap, lang = "receiver")] -#[cfg_attr(not(bootstrap), lang = "legacy_receiver")] +#[lang = "legacy_receiver"] #[unstable(feature = "legacy_receiver_trait", issue = "none")] #[doc(hidden)] pub trait LegacyReceiver { diff --git a/core/src/ops/drop.rs b/core/src/ops/drop.rs index a6f63ad68d695..e024b7fb4d301 100644 --- a/core/src/ops/drop.rs +++ b/core/src/ops/drop.rs @@ -203,7 +203,8 @@ /// [nomicon]: ../../nomicon/phantom-data.html#an-exception-the-special-case-of-the-standard-library-and-its-unstable-may_dangle #[lang = "drop"] #[stable(feature = "rust1", since = "1.0.0")] -// FIXME(const_trait_impl) #[const_trait] +#[const_trait] +#[rustc_const_unstable(feature = "const_destruct", issue = "133214")] pub trait Drop { /// Executes the destructor for this type. /// diff --git a/core/src/ops/mod.rs b/core/src/ops/mod.rs index cea1f84f3fd60..40526f9583e64 100644 --- a/core/src/ops/mod.rs +++ b/core/src/ops/mod.rs @@ -171,7 +171,6 @@ pub use self::deref::DerefPure; #[unstable(feature = "legacy_receiver_trait", issue = "none")] pub use self::deref::LegacyReceiver; #[unstable(feature = "arbitrary_self_types", issue = "44874")] -#[cfg(not(bootstrap))] pub use self::deref::Receiver; #[stable(feature = "rust1", since = "1.0.0")] pub use self::deref::{Deref, DerefMut}; diff --git a/core/src/option.rs b/core/src/option.rs index 29d1956af9559..a9f06b92ad5dd 100644 --- a/core/src/option.rs +++ b/core/src/option.rs @@ -563,7 +563,7 @@ use crate::pin::Pin; use crate::{cmp, convert, hint, mem, slice}; /// The `Option` type. See [the module level documentation](self) for more. -#[cfg_attr(not(bootstrap), doc(search_unbox))] +#[doc(search_unbox)] #[derive(Copy, Eq, Debug, Hash)] #[rustc_diagnostic_item = "Option"] #[lang = "Option"] @@ -738,7 +738,7 @@ impl Option { #[inline] #[must_use] #[stable(feature = "pin", since = "1.33.0")] - #[rustc_const_stable(feature = "const_option_ext", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_option_ext", since = "1.84.0")] pub const fn as_pin_ref(self: Pin<&Self>) -> Option> { // FIXME(const-hack): use `map` once that is possible match Pin::get_ref(self).as_ref() { @@ -755,7 +755,7 @@ impl Option { #[inline] #[must_use] #[stable(feature = "pin", since = "1.33.0")] - #[rustc_const_stable(feature = "const_option_ext", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_option_ext", since = "1.84.0")] pub const fn as_pin_mut(self: Pin<&mut Self>) -> Option> { // SAFETY: `get_unchecked_mut` is never used to move the `Option` inside `self`. // `x` is guaranteed to be pinned because it comes from `self` which is pinned. @@ -802,7 +802,7 @@ impl Option { #[inline] #[must_use] #[stable(feature = "option_as_slice", since = "1.75.0")] - #[rustc_const_stable(feature = "const_option_ext", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_option_ext", since = "1.84.0")] pub const fn as_slice(&self) -> &[T] { // SAFETY: When the `Option` is `Some`, we're using the actual pointer // to the payload, with a length of 1, so this is equivalent to @@ -857,7 +857,7 @@ impl Option { #[inline] #[must_use] #[stable(feature = "option_as_slice", since = "1.75.0")] - #[rustc_const_stable(feature = "const_option_ext", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_option_ext", since = "1.84.0")] pub const fn as_mut_slice(&mut self) -> &mut [T] { // SAFETY: When the `Option` is `Some`, we're using the actual pointer // to the payload, with a length of 1, so this is equivalent to @@ -937,10 +937,16 @@ impl Option { /// Returns the contained [`Some`] value, consuming the `self` value. /// /// Because this function may panic, its use is generally discouraged. + /// Panics are meant for unrecoverable errors, and + /// [may abort the entire program][panic-abort]. + /// /// Instead, prefer to use pattern matching and handle the [`None`] /// case explicitly, or call [`unwrap_or`], [`unwrap_or_else`], or - /// [`unwrap_or_default`]. + /// [`unwrap_or_default`]. In functions returning `Option`, you can use + /// [the `?` (try) operator][try-option]. /// + /// [panic-abort]: https://doc.rust-lang.org/book/ch09-01-unrecoverable-errors-with-panic.html + /// [try-option]: https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#where-the--operator-can-be-used /// [`unwrap_or`]: Option::unwrap_or /// [`unwrap_or_else`]: Option::unwrap_or_else /// [`unwrap_or_default`]: Option::unwrap_or_default diff --git a/core/src/panic.rs b/core/src/panic.rs index 179aadf0c286c..5fa340a6147f6 100644 --- a/core/src/panic.rs +++ b/core/src/panic.rs @@ -208,14 +208,13 @@ pub macro const_panic { #[rustc_allow_const_fn_unstable(const_eval_select)] #[inline(always)] // inline the wrapper #[track_caller] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_panic", since = "CURRENT_RUSTC_VERSION"))] const fn do_panic($($arg: $ty),*) -> ! { $crate::intrinsics::const_eval_select!( @capture { $($arg: $ty = $arg),* } -> !: #[noinline] if const #[track_caller] #[inline] { // Inline this, to prevent codegen $crate::panic!($const_msg) - } else #[track_caller] #[cfg_attr(bootstrap, inline)] { // Do not inline this, it makes perf worse + } else #[track_caller] { // Do not inline this, it makes perf worse $crate::panic!($runtime_msg) } ) diff --git a/core/src/panic/panic_info.rs b/core/src/panic/panic_info.rs index 230a9918dbf3e..9d53567a26fd9 100644 --- a/core/src/panic/panic_info.rs +++ b/core/src/panic/panic_info.rs @@ -165,7 +165,7 @@ impl<'a> PanicMessage<'a> { /// /// See [`fmt::Arguments::as_str`] for details. #[stable(feature = "panic_info_message", since = "1.81.0")] - #[rustc_const_stable(feature = "const_arguments_as_str", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_arguments_as_str", since = "1.84.0")] #[must_use] #[inline] pub const fn as_str(&self) -> Option<&'static str> { diff --git a/core/src/panicking.rs b/core/src/panicking.rs index f603eb2971f6d..53e2b238bae69 100644 --- a/core/src/panicking.rs +++ b/core/src/panicking.rs @@ -51,8 +51,7 @@ const _: () = assert!(cfg!(panic = "abort"), "panic_immediate_abort requires -C #[track_caller] #[lang = "panic_fmt"] // needed for const-evaluated panics #[rustc_do_not_const_check] // hooked by const-eval -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // must follow stable const rules since it is exposed to stable +#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { if cfg!(feature = "panic_immediate_abort") { super::intrinsics::abort() @@ -86,8 +85,7 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { // and unwinds anyway, we will hit the "unwinding out of nounwind function" guard, // which causes a "panic in a function that cannot unwind". #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // must follow stable const rules since it is exposed to stable +#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable #[rustc_allow_const_fn_unstable(const_eval_select)] pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: bool) -> ! { const_eval_select!( @@ -130,8 +128,7 @@ pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: boo #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // must follow stable const rules since it is exposed to stable +#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable #[lang = "panic"] // used by lints and miri for panics pub const fn panic(expr: &'static str) -> ! { // Use Arguments::new_const instead of format_args!("{expr}") to potentially @@ -169,8 +166,7 @@ macro_rules! panic_const { #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] - #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // must follow stable const rules since it is exposed to stable + #[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable #[lang = stringify!($lang)] pub const fn $lang() -> ! { // Use Arguments::new_const instead of format_args!("{expr}") to potentially @@ -217,8 +213,7 @@ panic_const! { #[cfg_attr(feature = "panic_immediate_abort", inline)] #[lang = "panic_nounwind"] // needed by codegen for non-unwinding panics #[rustc_nounwind] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // must follow stable const rules since it is exposed to stable +#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable pub const fn panic_nounwind(expr: &'static str) -> ! { panic_nounwind_fmt(fmt::Arguments::new_const(&[expr]), /* force_no_backtrace */ false); } @@ -234,8 +229,7 @@ pub fn panic_nounwind_nobacktrace(expr: &'static str) -> ! { #[track_caller] #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] #[cfg_attr(feature = "panic_immediate_abort", inline)] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // must follow stable const rules since it is exposed to stable +#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable pub const fn panic_explicit() -> ! { panic_display(&"explicit panic"); } @@ -252,8 +246,7 @@ pub fn unreachable_display(x: &T) -> ! { #[inline] #[track_caller] #[rustc_diagnostic_item = "panic_str_2015"] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // must follow stable const rules since it is exposed to stable +#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable pub const fn panic_str_2015(expr: &str) -> ! { panic_display(&expr); } @@ -263,8 +256,7 @@ pub const fn panic_str_2015(expr: &str) -> ! { #[rustc_do_not_const_check] // hooked by const-eval // enforce a &&str argument in const-check and hook this by const-eval #[rustc_const_panic_str] -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // must follow stable const rules since it is exposed to stable +#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable pub const fn panic_display(x: &T) -> ! { panic_fmt(format_args!("{}", *x)); } @@ -333,8 +325,7 @@ fn panic_in_cleanup() -> ! { /// This function is used instead of panic_fmt in const eval. #[lang = "const_panic_fmt"] // needed by const-eval machine to replace calls to `panic_fmt` lang item -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "panic_internals", issue = "none"))] -#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // must follow stable const rules since it is exposed to stable +#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable pub const fn const_panic_fmt(fmt: fmt::Arguments<'_>) -> ! { if let Some(msg) = fmt.as_str() { // The panic_display function is hooked by const eval. diff --git a/core/src/pat.rs b/core/src/pat.rs index 1f89d960be67b..752e79c2dacee 100644 --- a/core/src/pat.rs +++ b/core/src/pat.rs @@ -6,7 +6,7 @@ /// ``` #[macro_export] #[rustc_builtin_macro(pattern_type)] -#[unstable(feature = "core_pattern_type", issue = "123646")] +#[unstable(feature = "pattern_type_macro", issue = "123646")] macro_rules! pattern_type { ($($arg:tt)*) => { /* compiler built-in */ diff --git a/core/src/pin.rs b/core/src/pin.rs index c14c49a0d92f9..83730285636fb 100644 --- a/core/src/pin.rs +++ b/core/src/pin.rs @@ -373,9 +373,9 @@ //! exactly what we did with our `AddrTracker` example above. Without doing this, you *must not* //! rely on pinning-related guarantees to apply to your type! //! -//! If need to truly pin a value of a foreign or built-in type that implements [`Unpin`], you'll -//! need to create your own wrapper type around the [`Unpin`] type you want to pin and then -//! opts-out of [`Unpin`] using [`PhantomPinned`]. +//! If you really need to pin a value of a foreign or built-in type that implements [`Unpin`], +//! you'll need to create your own wrapper type around the [`Unpin`] type you want to pin and then +//! opt-out of [`Unpin`] using [`PhantomPinned`]. //! //! Exposing access to the inner field which you want to remain pinned must then be carefully //! considered as well! Remember, exposing a method that gives access to a @@ -595,7 +595,7 @@ //! [drop-impl]: self#implementing-drop-for-types-with-address-sensitive-states //! //! The [`drop`] function takes [`&mut self`], but this is called *even if that `self` has been -//! pinned*! Implementing [`Drop`] for a type with address-sensitive states, because if `self` was +//! pinned*! Implementing [`Drop`] for a type with address-sensitive states requires some care, because if `self` was //! indeed in an address-sensitive state before [`drop`] was called, it is as if the compiler //! automatically called [`Pin::get_unchecked_mut`]. //! @@ -1186,7 +1186,7 @@ impl> Pin { /// let mut pinned: Pin<&mut u8> = Pin::new(&mut val); /// ``` #[inline(always)] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] #[stable(feature = "pin", since = "1.33.0")] pub const fn new(pointer: Ptr) -> Pin { // SAFETY: the value pointed to is `Unpin`, and so has no requirements @@ -1215,7 +1215,7 @@ impl> Pin { /// ``` #[inline(always)] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] #[stable(feature = "pin_into_inner", since = "1.39.0")] pub const fn into_inner(pin: Pin) -> Ptr { pin.__pointer @@ -1352,7 +1352,7 @@ impl Pin { /// [`pin` module docs]: self #[lang = "new_unchecked"] #[inline(always)] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] #[stable(feature = "pin", since = "1.33.0")] pub const unsafe fn new_unchecked(pointer: Ptr) -> Pin { Pin { __pointer: pointer } @@ -1423,7 +1423,7 @@ impl Pin { /// move in the future, and this method does not enable the pointee to move. "Malicious" /// implementations of `Ptr::DerefMut` are likewise ruled out by the contract of /// `Pin::new_unchecked`. - #[stable(feature = "pin_deref_mut", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "pin_deref_mut", since = "1.84.0")] #[must_use = "`self` will be dropped if the result is not used"] #[inline(always)] pub fn as_deref_mut(self: Pin<&mut Pin>) -> Pin<&mut Ptr::Target> { @@ -1505,7 +1505,7 @@ impl Pin { /// instead. #[inline(always)] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] #[stable(feature = "pin_into_inner", since = "1.39.0")] pub const unsafe fn into_inner_unchecked(pin: Pin) -> Ptr { pin.__pointer @@ -1561,7 +1561,7 @@ impl<'a, T: ?Sized> Pin<&'a T> { /// ["pinning projections"]: self#projections-and-structural-pinning #[inline(always)] #[must_use] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] #[stable(feature = "pin", since = "1.33.0")] pub const fn get_ref(self) -> &'a T { self.__pointer @@ -1572,7 +1572,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { /// Converts this `Pin<&mut T>` into a `Pin<&T>` with the same lifetime. #[inline(always)] #[must_use = "`self` will be dropped if the result is not used"] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] #[stable(feature = "pin", since = "1.33.0")] pub const fn into_ref(self) -> Pin<&'a T> { Pin { __pointer: self.__pointer } @@ -1590,7 +1590,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { #[inline(always)] #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "pin", since = "1.33.0")] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] pub const fn get_mut(self) -> &'a mut T where T: Unpin, @@ -1611,7 +1611,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { #[inline(always)] #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "pin", since = "1.33.0")] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] pub const unsafe fn get_unchecked_mut(self) -> &'a mut T { self.__pointer } @@ -1654,7 +1654,7 @@ impl Pin<&'static T> { /// This is safe because `T` is borrowed immutably for the `'static` lifetime, which /// never ends. #[stable(feature = "pin_static_ref", since = "1.61.0")] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] pub const fn static_ref(r: &'static T) -> Pin<&'static T> { // SAFETY: The 'static borrow guarantees the data will not be // moved/invalidated until it gets dropped (which is never). @@ -1668,7 +1668,7 @@ impl Pin<&'static mut T> { /// This is safe because `T` is borrowed for the `'static` lifetime, which /// never ends. #[stable(feature = "pin_static_ref", since = "1.61.0")] - #[rustc_const_stable(feature = "const_pin", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_pin", since = "1.84.0")] pub const fn static_mut(r: &'static mut T) -> Pin<&'static mut T> { // SAFETY: The 'static borrow guarantees the data will not be // moved/invalidated until it gets dropped (which is never). diff --git a/core/src/prelude/mod.rs b/core/src/prelude/mod.rs index 496b78439ea6c..d3fda1cd273f9 100644 --- a/core/src/prelude/mod.rs +++ b/core/src/prelude/mod.rs @@ -71,7 +71,7 @@ pub mod rust_2021 { /// The 2024 version of the core prelude. /// /// See the [module-level documentation](self) for more. -#[unstable(feature = "prelude_2024", issue = "121042")] +#[stable(feature = "prelude_2024", since = "1.85.0")] pub mod rust_2024 { #[stable(feature = "rust1", since = "1.0.0")] pub use super::common::*; @@ -84,7 +84,7 @@ pub mod rust_2024 { #[doc(no_inline)] pub use crate::convert::{TryFrom, TryInto}; - #[unstable(feature = "prelude_2024", issue = "121042")] + #[stable(feature = "prelude_2024", since = "1.85.0")] #[doc(no_inline)] pub use crate::future::{Future, IntoFuture}; } diff --git a/core/src/primitive_docs.rs b/core/src/primitive_docs.rs index e105ceadff757..c5f029363e589 100644 --- a/core/src/primitive_docs.rs +++ b/core/src/primitive_docs.rs @@ -563,11 +563,11 @@ impl () {} /// Note that here the call to [`drop`] is for clarity - it indicates /// that we are done with the given value and it should be destroyed. /// -/// ## 3. Create it using `ptr::addr_of!` +/// ## 3. Create it using `&raw` /// -/// Instead of coercing a reference to a raw pointer, you can use the macros -/// [`ptr::addr_of!`] (for `*const T`) and [`ptr::addr_of_mut!`] (for `*mut T`). -/// These macros allow you to create raw pointers to fields to which you cannot +/// Instead of coercing a reference to a raw pointer, you can use the raw borrow +/// operators `&raw const` (for `*const T`) and `&raw mut` (for `*mut T`). +/// These operators allow you to create raw pointers to fields to which you cannot /// create a reference (without causing undefined behavior), such as an /// unaligned field. This might be necessary if packed structs or uninitialized /// memory is involved. @@ -580,7 +580,7 @@ impl () {} /// unaligned: u32, /// } /// let s = S::default(); -/// let p = std::ptr::addr_of!(s.unaligned); // not allowed with coercion +/// let p = &raw const s.unaligned; // not allowed with coercion /// ``` /// /// ## 4. Get it from C. diff --git a/core/src/ptr/alignment.rs b/core/src/ptr/alignment.rs index 2538d60a8eee9..74a1d40f4e734 100644 --- a/core/src/ptr/alignment.rs +++ b/core/src/ptr/alignment.rs @@ -41,7 +41,6 @@ impl Alignment { /// This provides the same numerical value as [`mem::align_of`], /// but in an `Alignment` instead of a `usize`. #[unstable(feature = "ptr_alignment_type", issue = "102070")] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070"))] #[inline] pub const fn of() -> Self { // SAFETY: rustc ensures that type alignment is always a power of two. @@ -53,7 +52,6 @@ impl Alignment { /// /// Note that `0` is not a power of two, nor a valid alignment. #[unstable(feature = "ptr_alignment_type", issue = "102070")] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070"))] #[inline] pub const fn new(align: usize) -> Option { if align.is_power_of_two() { @@ -73,7 +71,6 @@ impl Alignment { /// Equivalently, it must be `1 << exp` for some `exp` in `0..usize::BITS`. /// It must *not* be zero. #[unstable(feature = "ptr_alignment_type", issue = "102070")] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070"))] #[inline] pub const unsafe fn new_unchecked(align: usize) -> Self { assert_unsafe_precondition!( @@ -89,7 +86,6 @@ impl Alignment { /// Returns the alignment as a [`usize`]. #[unstable(feature = "ptr_alignment_type", issue = "102070")] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070"))] #[inline] pub const fn as_usize(self) -> usize { self.0 as usize @@ -97,7 +93,6 @@ impl Alignment { /// Returns the alignment as a [NonZero]<[usize]>. #[unstable(feature = "ptr_alignment_type", issue = "102070")] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070"))] #[inline] pub const fn as_nonzero(self) -> NonZero { // SAFETY: All the discriminants are non-zero. @@ -118,7 +113,6 @@ impl Alignment { /// assert_eq!(Alignment::new(1024).unwrap().log2(), 10); /// ``` #[unstable(feature = "ptr_alignment_type", issue = "102070")] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070"))] #[inline] pub const fn log2(self) -> u32 { self.as_nonzero().trailing_zeros() @@ -148,7 +142,6 @@ impl Alignment { /// assert_ne!(one.mask(Alignment::of::().mask()), one); /// ``` #[unstable(feature = "ptr_alignment_type", issue = "102070")] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070"))] #[inline] pub const fn mask(self) -> usize { // SAFETY: The alignment is always nonzero, and therefore decrementing won't overflow. diff --git a/core/src/ptr/const_ptr.rs b/core/src/ptr/const_ptr.rs index 0dbe819acb1b9..ec569291853a5 100644 --- a/core/src/ptr/const_ptr.rs +++ b/core/src/ptr/const_ptr.rs @@ -12,14 +12,17 @@ impl *const T { /// Therefore, two pointers that are null may still not compare equal to /// each other. /// - /// ## Behavior during const evaluation + /// # Panics during const evaluation /// - /// When this function is used during const evaluation, it may return `false` for pointers - /// that turn out to be null at runtime. Specifically, when a pointer to some memory - /// is offset beyond its bounds in such a way that the resulting pointer is null, - /// the function will still return `false`. There is no way for CTFE to know - /// the absolute position of that memory, so we cannot tell if the pointer is - /// null or not. + /// If this method is used during const evaluation, and `self` is a pointer + /// that is offset beyond the bounds of the memory it initially pointed to, + /// then there might not be enough information to determine whether the + /// pointer is null. This is because the absolute address in memory is not + /// known at compile time. If the nullness of the pointer cannot be + /// determined, this method will panic. + /// + /// In-bounds pointers are never null, so the method will never panic for + /// such pointers. /// /// # Examples /// @@ -29,7 +32,7 @@ impl *const T { /// assert!(!ptr.is_null()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_is_null", since = "1.84.0")] #[rustc_diagnostic_item = "ptr_const_is_null"] #[inline] #[rustc_allow_const_fn_unstable(const_eval_select)] @@ -113,7 +116,6 @@ impl *const T { /// println!("{:?}", unsafe { &*bad }); /// ``` #[unstable(feature = "set_ptr_value", issue = "75091")] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0"))] #[must_use = "returns a new pointer rather than modifying its argument"] #[inline] pub const fn with_metadata_of(self, meta: *const U) -> *const U @@ -159,7 +161,7 @@ impl *const T { /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] #[inline(always)] - #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn addr(self) -> usize { // A pointer-to-integer transmute currently has exactly the right semantics: it returns the // address without exposing the provenance. Note that this is *not* a stable guarantee about @@ -193,7 +195,7 @@ impl *const T { /// [`with_exposed_provenance`]: with_exposed_provenance #[must_use] #[inline(always)] - #[stable(feature = "exposed_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "exposed_provenance", since = "1.84.0")] pub fn expose_provenance(self) -> usize { self.cast::<()>() as usize } @@ -211,7 +213,7 @@ impl *const T { /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] #[inline] - #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn with_addr(self, addr: usize) -> Self { // This should probably be an intrinsic to avoid doing any sort of arithmetic, but // meanwhile, we can implement it with `wrapping_offset`, which preserves the pointer's @@ -230,7 +232,7 @@ impl *const T { /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] #[inline] - #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn map_addr(self, f: impl FnOnce(usize) -> usize) -> Self { self.with_addr(f(self.addr())) } @@ -255,6 +257,13 @@ impl *const T { /// When calling this method, you have to ensure that *either* the pointer is null *or* /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). /// + /// # Panics during const evaluation + /// + /// This method will panic during const evaluation if the pointer cannot be + /// determined to be null or not. See [`is_null`] for more information. + /// + /// [`is_null`]: #method.is_null + /// /// # Examples /// /// ``` @@ -282,7 +291,7 @@ impl *const T { /// } /// ``` #[stable(feature = "ptr_as_ref", since = "1.9.0")] - #[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_is_null", since = "1.84.0")] #[inline] pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> { // SAFETY: the caller must guarantee that `self` is valid @@ -332,6 +341,13 @@ impl *const T { /// When calling this method, you have to ensure that *either* the pointer is null *or* /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). /// + /// # Panics during const evaluation + /// + /// This method will panic during const evaluation if the pointer cannot be + /// determined to be null or not. See [`is_null`] for more information. + /// + /// [`is_null`]: #method.is_null + /// /// # Examples /// /// ``` @@ -347,7 +363,6 @@ impl *const T { /// ``` #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] - #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")] pub const unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit> where T: Sized, @@ -504,11 +519,12 @@ impl *const T { /// let mut out = String::new(); /// while ptr != end_rounded_up { /// unsafe { - /// write!(&mut out, "{}, ", *ptr).unwrap(); + /// write!(&mut out, "{}, ", *ptr)?; /// } /// ptr = ptr.wrapping_offset(step); /// } /// assert_eq!(out.as_str(), "1, 3, 5, "); + /// # std::fmt::Result::Ok(()) /// ``` #[stable(feature = "ptr_wrapping_offset", since = "1.16.0")] #[must_use = "returns a new pointer rather than modifying its argument"] @@ -1018,7 +1034,6 @@ impl *const T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub(self, count: usize) -> Self @@ -1128,11 +1143,12 @@ impl *const T { /// let mut out = String::new(); /// while ptr != end_rounded_up { /// unsafe { - /// write!(&mut out, "{}, ", *ptr).unwrap(); + /// write!(&mut out, "{}, ", *ptr)?; /// } /// ptr = ptr.wrapping_add(step); /// } /// assert_eq!(out, "1, 3, 5, "); + /// # std::fmt::Result::Ok(()) /// ``` #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] @@ -1206,11 +1222,12 @@ impl *const T { /// let mut out = String::new(); /// while ptr != start_rounded_down { /// unsafe { - /// write!(&mut out, "{}, ", *ptr).unwrap(); + /// write!(&mut out, "{}, ", *ptr)?; /// } /// ptr = ptr.wrapping_sub(step); /// } /// assert_eq!(out, "5, 3, 1, "); + /// # std::fmt::Result::Ok(()) /// ``` #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] @@ -1526,6 +1543,21 @@ impl *const [T] { self as *const T } + /// Gets a raw pointer to the underlying array. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub const fn as_array(self) -> Option<*const [T; N]> { + if self.len() == N { + let me = self.as_ptr() as *const [T; N]; + Some(me) + } else { + None + } + } + /// Returns a raw pointer to an element or subslice, without doing bounds /// checking. /// @@ -1592,9 +1624,15 @@ impl *const [T] { /// /// [valid]: crate::ptr#safety /// [allocated object]: crate::ptr#allocated-object + /// + /// # Panics during const evaluation + /// + /// This method will panic during const evaluation if the pointer cannot be + /// determined to be null or not. See [`is_null`] for more information. + /// + /// [`is_null`]: #method.is_null #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] - #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")] pub const unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit]> { if self.is_null() { None diff --git a/core/src/ptr/metadata.rs b/core/src/ptr/metadata.rs index 5f20cb2ee7206..e93b5658e2436 100644 --- a/core/src/ptr/metadata.rs +++ b/core/src/ptr/metadata.rs @@ -53,7 +53,8 @@ use crate::ptr::NonNull; /// /// [`to_raw_parts`]: *const::to_raw_parts #[lang = "pointee_trait"] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[rustc_deny_explicit_impl] +#[rustc_do_not_implement_via_object] pub trait Pointee { /// The type for metadata in pointers and references to `Self`. #[lang = "metadata_type"] @@ -92,7 +93,6 @@ pub trait Thin = Pointee; /// /// assert_eq!(std::ptr::metadata("foo"), 3_usize); /// ``` -#[cfg_attr(bootstrap, rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0"))] #[inline] pub const fn metadata(ptr: *const T) -> ::Metadata { ptr_metadata(ptr) @@ -106,7 +106,6 @@ pub const fn metadata(ptr: *const T) -> ::Metadata { /// /// [`slice::from_raw_parts`]: crate::slice::from_raw_parts #[unstable(feature = "ptr_metadata", issue = "81513")] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0"))] #[inline] pub const fn from_raw_parts( data_pointer: *const impl Thin, @@ -120,7 +119,6 @@ pub const fn from_raw_parts( /// /// See the documentation of [`from_raw_parts`] for more details. #[unstable(feature = "ptr_metadata", issue = "81513")] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0"))] #[inline] pub const fn from_raw_parts_mut( data_pointer: *mut impl Thin, diff --git a/core/src/ptr/mod.rs b/core/src/ptr/mod.rs index 805edddfe6312..f58c0e1241142 100644 --- a/core/src/ptr/mod.rs +++ b/core/src/ptr/mod.rs @@ -15,8 +15,8 @@ //! The precise rules for validity are not determined yet. The guarantees that are //! provided at this point are very minimal: //! -//! * For operations of [size zero][zst], *every* pointer is valid, including the [null] pointer. -//! The following points are only concerned with non-zero-sized accesses. +//! * For memory accesses of [size zero][zst], *every* pointer is valid, including the [null] +//! pointer. The following points are only concerned with non-zero-sized accesses. //! * A [null] pointer is *never* valid. //! * For a pointer to be valid, it is necessary, but not always sufficient, that the pointer be //! *dereferenceable*. The [provenance] of the pointer is used to determine which [allocated @@ -84,7 +84,7 @@ // ^ we use this term instead of saying that the produced reference must // be valid, as the validity of a reference is easily confused for the // validity of the thing it refers to, and while the two concepts are -// closly related, they are not identical. +// closely related, they are not identical. //! //! These rules apply even if the result is unused! //! (The part about being initialized is not yet fully decided, but until @@ -200,7 +200,7 @@ //! //! But it *is* still sound to: //! -//! * Create a pointer without provenance from just an address (see [`ptr::dangling`]). Such a +//! * Create a pointer without provenance from just an address (see [`without_provenance`]). Such a //! pointer cannot be used for memory accesses (except for zero-sized accesses). This can still be //! useful for sentinel values like `null` *or* to represent a tagged pointer that will never be //! dereferenceable. In general, it is always sound for an integer to pretend to be a pointer "for @@ -314,8 +314,8 @@ //! } //! ``` //! -//! (Yes, if you've been using AtomicUsize for pointers in concurrent datastructures, you should -//! be using AtomicPtr instead. If that messes up the way you atomically manipulate pointers, +//! (Yes, if you've been using [`AtomicUsize`] for pointers in concurrent datastructures, you should +//! be using [`AtomicPtr`] instead. If that messes up the way you atomically manipulate pointers, //! we would like to know why, and what needs to be done to fix it.) //! //! Situations where a valid pointer *must* be created from just an address, such as baremetal code @@ -381,7 +381,8 @@ //! [`with_addr`]: pointer::with_addr //! [`map_addr`]: pointer::map_addr //! [`addr`]: pointer::addr -//! [`ptr::dangling`]: core::ptr::dangling +//! [`AtomicUsize`]: crate::sync::atomic::AtomicUsize +//! [`AtomicPtr`]: crate::sync::atomic::AtomicPtr //! [`expose_provenance`]: pointer::expose_provenance //! [`with_exposed_provenance`]: with_exposed_provenance //! [Miri]: https://github.com/rust-lang/miri @@ -394,6 +395,7 @@ #![allow(clippy::not_unsafe_ptr_arg_deref)] use crate::cmp::Ordering; +use crate::intrinsics::const_eval_select; use crate::marker::FnPtr; use crate::mem::{self, MaybeUninit, SizedTypeProperties}; use crate::{fmt, hash, intrinsics, ub_checks}; @@ -591,8 +593,8 @@ pub const fn null_mut() -> *mut T { /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[inline(always)] #[must_use] -#[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] -#[rustc_const_stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "strict_provenance", since = "1.84.0")] +#[rustc_const_stable(feature = "strict_provenance", since = "1.84.0")] pub const fn without_provenance(addr: usize) -> *const T { // An int-to-pointer transmute currently has exactly the intended semantics: it creates a // pointer without provenance. Note that this is *not* a stable guarantee about transmute @@ -613,8 +615,8 @@ pub const fn without_provenance(addr: usize) -> *const T { /// some other means. #[inline(always)] #[must_use] -#[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] -#[rustc_const_stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "strict_provenance", since = "1.84.0")] +#[rustc_const_stable(feature = "strict_provenance", since = "1.84.0")] pub const fn dangling() -> *const T { without_provenance(mem::align_of::()) } @@ -634,8 +636,8 @@ pub const fn dangling() -> *const T { /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[inline(always)] #[must_use] -#[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] -#[rustc_const_stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "strict_provenance", since = "1.84.0")] +#[rustc_const_stable(feature = "strict_provenance", since = "1.84.0")] pub const fn without_provenance_mut(addr: usize) -> *mut T { // An int-to-pointer transmute currently has exactly the intended semantics: it creates a // pointer without provenance. Note that this is *not* a stable guarantee about transmute @@ -656,8 +658,8 @@ pub const fn without_provenance_mut(addr: usize) -> *mut T { /// some other means. #[inline(always)] #[must_use] -#[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] -#[rustc_const_stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "strict_provenance", since = "1.84.0")] +#[rustc_const_stable(feature = "strict_provenance", since = "1.84.0")] pub const fn dangling_mut() -> *mut T { without_provenance_mut(mem::align_of::()) } @@ -695,7 +697,7 @@ pub const fn dangling_mut() -> *mut T { /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API. #[must_use] #[inline(always)] -#[stable(feature = "exposed_provenance", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "exposed_provenance", since = "1.84.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[allow(fuzzy_provenance_casts)] // this *is* the explicit provenance API one should use instead pub fn with_exposed_provenance(addr: usize) -> *const T { @@ -735,7 +737,7 @@ pub fn with_exposed_provenance(addr: usize) -> *const T { /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API. #[must_use] #[inline(always)] -#[stable(feature = "exposed_provenance", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "exposed_provenance", since = "1.84.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[allow(fuzzy_provenance_casts)] // this *is* the explicit provenance API one should use instead pub fn with_exposed_provenance_mut(addr: usize) -> *mut T { @@ -775,7 +777,7 @@ pub fn with_exposed_provenance_mut(addr: usize) -> *mut T { /// # type T = i32; /// # fn foo() -> T { 42 } /// // The temporary holding the return value of `foo` does *not* have its lifetime extended, -/// // because the surrounding expression involves no function call. +/// // because the surrounding expression involves a function call. /// let p = ptr::from_ref(&foo()); /// unsafe { p.read() }; // UB! Reading from a dangling pointer ⚠️ /// ``` @@ -826,7 +828,7 @@ pub const fn from_ref(r: &T) -> *const T { /// # type T = i32; /// # fn foo() -> T { 42 } /// // The temporary holding the return value of `foo` does *not* have its lifetime extended, -/// // because the surrounding expression involves no function call. +/// // because the surrounding expression involves a function call. /// let p = ptr::from_mut(&mut foo()); /// unsafe { p.write(T::default()) }; // UB! Writing to a dangling pointer ⚠️ /// ``` @@ -1007,7 +1009,7 @@ pub const fn slice_from_raw_parts_mut(data: *mut T, len: usize) -> *mut [T] { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_swap", issue = "83163")] +#[rustc_const_stable(feature = "const_swap", since = "1.85.0")] #[rustc_diagnostic_item = "ptr_swap"] pub const unsafe fn swap(x: *mut T, y: *mut T) { // Give ourselves some scratch space to work with. @@ -1069,28 +1071,9 @@ pub const unsafe fn swap(x: *mut T, y: *mut T) { /// ``` #[inline] #[stable(feature = "swap_nonoverlapping", since = "1.27.0")] -#[rustc_const_unstable(feature = "const_swap", issue = "83163")] +#[rustc_const_unstable(feature = "const_swap_nonoverlapping", issue = "133668")] #[rustc_diagnostic_item = "ptr_swap_nonoverlapping"] pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { - #[allow(unused)] - macro_rules! attempt_swap_as_chunks { - ($ChunkTy:ty) => { - if mem::align_of::() >= mem::align_of::<$ChunkTy>() - && mem::size_of::() % mem::size_of::<$ChunkTy>() == 0 - { - let x: *mut $ChunkTy = x.cast(); - let y: *mut $ChunkTy = y.cast(); - let count = count * (mem::size_of::() / mem::size_of::<$ChunkTy>()); - // SAFETY: these are the same bytes that the caller promised were - // ok, just typed as `MaybeUninit`s instead of as `T`s. - // The `if` condition above ensures that we're not violating - // alignment requirements, and that the division is exact so - // that we don't lose any bytes off the end. - return unsafe { swap_nonoverlapping_simple_untyped(x, y, count) }; - } - }; - } - ub_checks::assert_unsafe_precondition!( check_language_ub, "ptr::swap_nonoverlapping requires that both pointer arguments are aligned and non-null \ @@ -1109,19 +1092,48 @@ pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { } ); - // Split up the slice into small power-of-two-sized chunks that LLVM is able - // to vectorize (unless it's a special type with more-than-pointer alignment, - // because we don't want to pessimize things like slices of SIMD vectors.) - if mem::align_of::() <= mem::size_of::() - && (!mem::size_of::().is_power_of_two() - || mem::size_of::() > mem::size_of::() * 2) - { - attempt_swap_as_chunks!(usize); - attempt_swap_as_chunks!(u8); - } + const_eval_select!( + @capture[T] { x: *mut T, y: *mut T, count: usize }: + if const { + // At compile-time we want to always copy this in chunks of `T`, to ensure that if there + // are pointers inside `T` we will copy them in one go rather than trying to copy a part + // of a pointer (which would not work). + // SAFETY: Same preconditions as this function + unsafe { swap_nonoverlapping_simple_untyped(x, y, count) } + } else { + macro_rules! attempt_swap_as_chunks { + ($ChunkTy:ty) => { + if mem::align_of::() >= mem::align_of::<$ChunkTy>() + && mem::size_of::() % mem::size_of::<$ChunkTy>() == 0 + { + let x: *mut $ChunkTy = x.cast(); + let y: *mut $ChunkTy = y.cast(); + let count = count * (mem::size_of::() / mem::size_of::<$ChunkTy>()); + // SAFETY: these are the same bytes that the caller promised were + // ok, just typed as `MaybeUninit`s instead of as `T`s. + // The `if` condition above ensures that we're not violating + // alignment requirements, and that the division is exact so + // that we don't lose any bytes off the end. + return unsafe { swap_nonoverlapping_simple_untyped(x, y, count) }; + } + }; + } + + // Split up the slice into small power-of-two-sized chunks that LLVM is able + // to vectorize (unless it's a special type with more-than-pointer alignment, + // because we don't want to pessimize things like slices of SIMD vectors.) + if mem::align_of::() <= mem::size_of::() + && (!mem::size_of::().is_power_of_two() + || mem::size_of::() > mem::size_of::() * 2) + { + attempt_swap_as_chunks!(usize); + attempt_swap_as_chunks!(u8); + } - // SAFETY: Same preconditions as this function - unsafe { swap_nonoverlapping_simple_untyped(x, y, count) } + // SAFETY: Same preconditions as this function + unsafe { swap_nonoverlapping_simple_untyped(x, y, count) } + } + ) } /// Same behavior and safety conditions as [`swap_nonoverlapping`] @@ -1129,7 +1141,6 @@ pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { /// LLVM can vectorize this (at least it can for the power-of-two-sized types /// `swap_nonoverlapping` tries to use) so no need to manually SIMD it. #[inline] -#[rustc_const_unstable(feature = "const_swap", issue = "83163")] const unsafe fn swap_nonoverlapping_simple_untyped(x: *mut T, y: *mut T, count: usize) { let x = x.cast::>(); let y = y.cast::>(); @@ -1392,8 +1403,6 @@ pub const unsafe fn read(src: *const T) -> T { /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the returned /// value and the value at `*src` can [violate memory safety][read-ownership]. /// -/// Note that even if `T` has size `0`, the pointer must be non-null. -/// /// [read-ownership]: read#ownership-of-the-returned-value /// [valid]: self#safety /// @@ -1600,8 +1609,6 @@ pub const unsafe fn write(dst: *mut T, src: T) { /// /// * `dst` must be [valid] for writes. /// -/// Note that even if `T` has size `0`, the pointer must be non-null. -/// /// [valid]: self#safety /// /// ## On `packed` structs @@ -2111,7 +2118,6 @@ pub fn addr_eq(p: *const T, q: *const U) -> bool { /// when compiled with optimization: /// /// ``` -/// # #![feature(ptr_fn_addr_eq)] /// let f: fn(i32) -> i32 = |x| x; /// let g: fn(i32) -> i32 = |x| x + 0; // different closure, different body /// let h: fn(u32) -> u32 = |x| x + 0; // different signature too @@ -2136,7 +2142,6 @@ pub fn addr_eq(p: *const T, q: *const U) -> bool { /// # Examples /// /// ``` -/// #![feature(ptr_fn_addr_eq)] /// use std::ptr; /// /// fn a() { println!("a"); } @@ -2145,7 +2150,7 @@ pub fn addr_eq(p: *const T, q: *const U) -> bool { /// ``` /// /// [subtype]: https://doc.rust-lang.org/reference/subtyping.html -#[unstable(feature = "ptr_fn_addr_eq", issue = "129322")] +#[stable(feature = "ptr_fn_addr_eq", since = "1.85.0")] #[inline(always)] #[must_use = "function pointer comparison produces a value"] pub fn fn_addr_eq(f: T, g: U) -> bool { diff --git a/core/src/ptr/mut_ptr.rs b/core/src/ptr/mut_ptr.rs index f0204bd0f773d..5d9d337f101a5 100644 --- a/core/src/ptr/mut_ptr.rs +++ b/core/src/ptr/mut_ptr.rs @@ -12,14 +12,17 @@ impl *mut T { /// Therefore, two pointers that are null may still not compare equal to /// each other. /// - /// ## Behavior during const evaluation + /// # Panics during const evaluation /// - /// When this function is used during const evaluation, it may return `false` for pointers - /// that turn out to be null at runtime. Specifically, when a pointer to some memory - /// is offset beyond its bounds in such a way that the resulting pointer is null, - /// the function will still return `false`. There is no way for CTFE to know - /// the absolute position of that memory, so we cannot tell if the pointer is - /// null or not. + /// If this method is used during const evaluation, and `self` is a pointer + /// that is offset beyond the bounds of the memory it initially pointed to, + /// then there might not be enough information to determine whether the + /// pointer is null. This is because the absolute address in memory is not + /// known at compile time. If the nullness of the pointer cannot be + /// determined, this method will panic. + /// + /// In-bounds pointers are never null, so the method will never panic for + /// such pointers. /// /// # Examples /// @@ -29,7 +32,7 @@ impl *mut T { /// assert!(!ptr.is_null()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_is_null", since = "1.84.0")] #[rustc_diagnostic_item = "ptr_is_null"] #[inline] pub const fn is_null(self) -> bool { @@ -94,7 +97,6 @@ impl *mut T { /// // This dereference is UB. The pointer only has provenance for `x` but points to `y`. /// println!("{:?}", unsafe { &*bad }); #[unstable(feature = "set_ptr_value", issue = "75091")] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0"))] #[must_use = "returns a new pointer rather than modifying its argument"] #[inline] pub const fn with_metadata_of(self, meta: *const U) -> *mut U @@ -146,7 +148,7 @@ impl *mut T { /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] #[inline(always)] - #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn addr(self) -> usize { // A pointer-to-integer transmute currently has exactly the right semantics: it returns the // address without exposing the provenance. Note that this is *not* a stable guarantee about @@ -179,7 +181,7 @@ impl *mut T { /// /// [`with_exposed_provenance_mut`]: with_exposed_provenance_mut #[inline(always)] - #[stable(feature = "exposed_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "exposed_provenance", since = "1.84.0")] pub fn expose_provenance(self) -> usize { self.cast::<()>() as usize } @@ -197,7 +199,7 @@ impl *mut T { /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] #[inline] - #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn with_addr(self, addr: usize) -> Self { // This should probably be an intrinsic to avoid doing any sort of arithmetic, but // meanwhile, we can implement it with `wrapping_offset`, which preserves the pointer's @@ -216,7 +218,7 @@ impl *mut T { /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] #[inline] - #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn map_addr(self, f: impl FnOnce(usize) -> usize) -> Self { self.with_addr(f(self.addr())) } @@ -244,6 +246,13 @@ impl *mut T { /// When calling this method, you have to ensure that *either* the pointer is null *or* /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). /// + /// # Panics during const evaluation + /// + /// This method will panic during const evaluation if the pointer cannot be + /// determined to be null or not. See [`is_null`] for more information. + /// + /// [`is_null`]: #method.is_null-1 + /// /// # Examples /// /// ``` @@ -271,7 +280,7 @@ impl *mut T { /// } /// ``` #[stable(feature = "ptr_as_ref", since = "1.9.0")] - #[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_is_null", since = "1.84.0")] #[inline] pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> { // SAFETY: the caller must guarantee that `self` is valid for a @@ -328,6 +337,13 @@ impl *mut T { /// Note that because the created reference is to `MaybeUninit`, the /// source pointer can point to uninitialized memory. /// + /// # Panics during const evaluation + /// + /// This method will panic during const evaluation if the pointer cannot be + /// determined to be null or not. See [`is_null`] for more information. + /// + /// [`is_null`]: #method.is_null-1 + /// /// # Examples /// /// ``` @@ -343,7 +359,6 @@ impl *mut T { /// ``` #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] - #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")] pub const unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit> where T: Sized, @@ -592,6 +607,12 @@ impl *mut T { /// the pointer is null *or* /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). /// + /// # Panics during const evaluation + /// + /// This method will panic during const evaluation if the pointer cannot be + /// determined to be null or not. See [`is_null`] for more information. + /// + /// [`is_null`]: #method.is_null-1 /// /// # Examples /// @@ -619,7 +640,7 @@ impl *mut T { /// println!("{s:?}"); // It'll print: "[4, 2, 3]". /// ``` #[stable(feature = "ptr_as_ref", since = "1.9.0")] - #[rustc_const_stable(feature = "const_ptr_is_null", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_is_null", since = "1.84.0")] #[inline] pub const unsafe fn as_mut<'a>(self) -> Option<&'a mut T> { // SAFETY: the caller must guarantee that `self` is be valid for @@ -675,9 +696,15 @@ impl *mut T { /// /// When calling this method, you have to ensure that *either* the pointer is null *or* /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). + /// + /// # Panics during const evaluation + /// + /// This method will panic during const evaluation if the pointer cannot be + /// determined to be null or not. See [`is_null`] for more information. + /// + /// [`is_null`]: #method.is_null-1 #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] - #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")] pub const unsafe fn as_uninit_mut<'a>(self) -> Option<&'a mut MaybeUninit> where T: Sized, @@ -1097,7 +1124,6 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub(self, count: usize) -> Self @@ -1568,7 +1594,7 @@ impl *mut T { /// /// [`ptr::swap`]: crate::ptr::swap() #[stable(feature = "pointer_methods", since = "1.26.0")] - #[rustc_const_unstable(feature = "const_swap", issue = "83163")] + #[rustc_const_stable(feature = "const_swap", since = "1.85.0")] #[inline(always)] pub const unsafe fn swap(self, with: *mut T) where @@ -1591,15 +1617,6 @@ impl *mut T { /// beyond the allocation that the pointer points into. It is up to the caller to ensure that /// the returned offset is correct in all terms other than alignment. /// - /// When this is called during compile-time evaluation (which is unstable), the implementation - /// may return `usize::MAX` in cases where that can never happen at runtime. This is because the - /// actual alignment of pointers is not known yet during compile-time, so an offset with - /// guaranteed alignment can sometimes not be computed. For example, a buffer declared as `[u8; - /// N]` might be allocated at an odd or an even address, but at compile-time this is not yet - /// known, so the execution has to be correct for either choice. It is therefore impossible to - /// find an offset that is guaranteed to be 2-aligned. (This behavior is subject to change, as usual - /// for unstable APIs.) - /// /// # Panics /// /// The function panics if `align` is not a power-of-two. @@ -1760,6 +1777,21 @@ impl *mut [T] { self.len() == 0 } + /// Gets a raw, mutable pointer to the underlying array. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub const fn as_mut_array(self) -> Option<*mut [T; N]> { + if self.len() == N { + let me = self.as_mut_ptr() as *mut [T; N]; + Some(me) + } else { + None + } + } + /// Divides one mutable raw slice into two at an index. /// /// The first will contain all indices from `[0, mid)` (excluding @@ -1947,9 +1979,15 @@ impl *mut [T] { /// /// [valid]: crate::ptr#safety /// [allocated object]: crate::ptr#allocated-object + /// + /// # Panics during const evaluation + /// + /// This method will panic during const evaluation if the pointer cannot be + /// determined to be null or not. See [`is_null`] for more information. + /// + /// [`is_null`]: #method.is_null-1 #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] - #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")] pub const unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit]> { if self.is_null() { None @@ -1999,9 +2037,15 @@ impl *mut [T] { /// /// [valid]: crate::ptr#safety /// [allocated object]: crate::ptr#allocated-object + /// + /// # Panics during const evaluation + /// + /// This method will panic during const evaluation if the pointer cannot be + /// determined to be null or not. See [`is_null`] for more information. + /// + /// [`is_null`]: #method.is_null-1 #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] - #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")] pub const unsafe fn as_uninit_slice_mut<'a>(self) -> Option<&'a mut [MaybeUninit]> { if self.is_null() { None diff --git a/core/src/ptr/non_null.rs b/core/src/ptr/non_null.rs index b69f8a4b9d3ea..2c9131254f7c4 100644 --- a/core/src/ptr/non_null.rs +++ b/core/src/ptr/non_null.rs @@ -7,7 +7,7 @@ use crate::pin::PinCoerceUnsized; use crate::ptr::Unique; use crate::slice::{self, SliceIndex}; use crate::ub_checks::assert_unsafe_precondition; -use crate::{fmt, hash, intrinsics, ptr}; +use crate::{fmt, hash, intrinsics, mem, ptr}; /// `*mut T` but non-zero and [covariant]. /// @@ -69,6 +69,8 @@ use crate::{fmt, hash, intrinsics, ptr}; #[rustc_nonnull_optimization_guaranteed] #[rustc_diagnostic_item = "NonNull"] pub struct NonNull { + // Remember to use `.as_ptr()` instead of `.pointer`, as field projecting to + // this is banned by . pointer: *const T, } @@ -83,6 +85,20 @@ impl !Send for NonNull {} impl !Sync for NonNull {} impl NonNull { + /// Creates a pointer with the given address and no [provenance][crate::ptr#provenance]. + /// + /// For more details, see the equivalent method on a raw pointer, [`ptr::without_provenance_mut`]. + /// + /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. + #[unstable(feature = "nonnull_provenance", issue = "135243")] + pub const fn without_provenance(addr: NonZero) -> Self { + // SAFETY: we know `addr` is non-zero. + unsafe { + let ptr = crate::ptr::without_provenance_mut(addr.get()); + NonNull::new_unchecked(ptr) + } + } + /// Creates a new `NonNull` that is dangling, but well-aligned. /// /// This is useful for initializing types which lazily allocate, like @@ -114,6 +130,21 @@ impl NonNull { } } + /// Converts an address back to a mutable pointer, picking up some previously 'exposed' + /// [provenance][crate::ptr#provenance]. + /// + /// For more details, see the equivalent method on a raw pointer, [`ptr::with_exposed_provenance_mut`]. + /// + /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API. + #[unstable(feature = "nonnull_provenance", issue = "135243")] + pub fn with_exposed_provenance(addr: NonZero) -> Self { + // SAFETY: we know `addr` is non-zero. + unsafe { + let ptr = crate::ptr::with_exposed_provenance_mut(addr.get()); + NonNull::new_unchecked(ptr) + } + } + /// Returns a shared references to the value. In contrast to [`as_ref`], this does not require /// that the value has to be initialized. /// @@ -202,6 +233,13 @@ impl NonNull { /// Creates a new `NonNull` if `ptr` is non-null. /// + /// # Panics during const evaluation + /// + /// This method will panic during const evaluation if the pointer cannot be + /// determined to be null or not. See [`is_null`] for more information. + /// + /// [`is_null`]: ../primitive.pointer.html#method.is_null-1 + /// /// # Examples /// /// ``` @@ -215,7 +253,7 @@ impl NonNull { /// } /// ``` #[stable(feature = "nonnull", since = "1.25.0")] - #[rustc_const_unstable(feature = "const_nonnull_new", issue = "93235")] + #[rustc_const_stable(feature = "const_nonnull_new", since = "1.85.0")] #[inline] pub const fn new(ptr: *mut T) -> Option { if !ptr.is_null() { @@ -273,41 +311,54 @@ impl NonNull { /// Gets the "address" portion of the pointer. /// - /// For more details see the equivalent method on a raw pointer, [`pointer::addr`]. + /// For more details, see the equivalent method on a raw pointer, [`pointer::addr`]. /// /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] #[inline] - #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn addr(self) -> NonZero { // SAFETY: The pointer is guaranteed by the type to be non-null, // meaning that the address will be non-zero. - unsafe { NonZero::new_unchecked(self.pointer.addr()) } + unsafe { NonZero::new_unchecked(self.as_ptr().addr()) } + } + + /// Exposes the ["provenance"][crate::ptr#provenance] part of the pointer for future use in + /// [`with_exposed_provenance`][NonNull::with_exposed_provenance] and returns the "address" portion. + /// + /// For more details, see the equivalent method on a raw pointer, [`pointer::expose_provenance`]. + /// + /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API. + #[unstable(feature = "nonnull_provenance", issue = "135243")] + pub fn expose_provenance(self) -> NonZero { + // SAFETY: The pointer is guaranteed by the type to be non-null, + // meaning that the address will be non-zero. + unsafe { NonZero::new_unchecked(self.as_ptr().expose_provenance()) } } /// Creates a new pointer with the given address and the [provenance][crate::ptr#provenance] of /// `self`. /// - /// For more details see the equivalent method on a raw pointer, [`pointer::with_addr`]. + /// For more details, see the equivalent method on a raw pointer, [`pointer::with_addr`]. /// /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] #[inline] - #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn with_addr(self, addr: NonZero) -> Self { // SAFETY: The result of `ptr::from::with_addr` is non-null because `addr` is guaranteed to be non-zero. - unsafe { NonNull::new_unchecked(self.pointer.with_addr(addr.get()) as *mut _) } + unsafe { NonNull::new_unchecked(self.as_ptr().with_addr(addr.get()) as *mut _) } } /// Creates a new pointer by mapping `self`'s address to a new one, preserving the /// [provenance][crate::ptr#provenance] of `self`. /// - /// For more details see the equivalent method on a raw pointer, [`pointer::map_addr`]. + /// For more details, see the equivalent method on a raw pointer, [`pointer::map_addr`]. /// /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[must_use] #[inline] - #[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "strict_provenance", since = "1.84.0")] pub fn map_addr(self, f: impl FnOnce(NonZero) -> NonZero) -> Self { self.with_addr(f(self.addr())) } @@ -335,7 +386,12 @@ impl NonNull { #[must_use] #[inline(always)] pub const fn as_ptr(self) -> *mut T { - self.pointer as *mut T + // This is a transmute for the same reasons as `NonZero::get`. + + // SAFETY: `NonNull` is `transparent` over a `*const T`, and `*const T` + // and `*mut T` have the same layout, so transitively we can transmute + // our `NonNull` to a `*mut T` directly. + unsafe { mem::transmute::(self) } } /// Returns a shared reference to the value. If the value may be uninitialized, [`as_uninit_ref`] @@ -484,7 +540,7 @@ impl NonNull { // Additionally safety contract of `offset` guarantees that the resulting pointer is // pointing to an allocation, there can't be an allocation at null, thus it's safe to // construct `NonNull`. - unsafe { NonNull { pointer: intrinsics::offset(self.pointer, count) } } + unsafe { NonNull { pointer: intrinsics::offset(self.as_ptr(), count) } } } /// Calculates the offset from a pointer in bytes. @@ -508,7 +564,7 @@ impl NonNull { // Additionally safety contract of `offset` guarantees that the resulting pointer is // pointing to an allocation, there can't be an allocation at null, thus it's safe to // construct `NonNull`. - unsafe { NonNull { pointer: self.pointer.byte_offset(count) } } + unsafe { NonNull { pointer: self.as_ptr().byte_offset(count) } } } /// Adds an offset to a pointer (convenience for `.offset(count as isize)`). @@ -560,7 +616,7 @@ impl NonNull { // Additionally safety contract of `offset` guarantees that the resulting pointer is // pointing to an allocation, there can't be an allocation at null, thus it's safe to // construct `NonNull`. - unsafe { NonNull { pointer: intrinsics::offset(self.pointer, count) } } + unsafe { NonNull { pointer: intrinsics::offset(self.as_ptr(), count) } } } /// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`). @@ -584,7 +640,7 @@ impl NonNull { // Additionally safety contract of `add` guarantees that the resulting pointer is pointing // to an allocation, there can't be an allocation at null, thus it's safe to construct // `NonNull`. - unsafe { NonNull { pointer: self.pointer.byte_add(count) } } + unsafe { NonNull { pointer: self.as_ptr().byte_add(count) } } } /// Subtracts an offset from a pointer (convenience for @@ -629,7 +685,6 @@ impl NonNull { #[must_use = "returns a new pointer rather than modifying its argument"] #[stable(feature = "non_null_convenience", since = "1.80.0")] #[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))] pub const unsafe fn sub(self, count: usize) -> Self where T: Sized, @@ -667,7 +722,7 @@ impl NonNull { // Additionally safety contract of `sub` guarantees that the resulting pointer is pointing // to an allocation, there can't be an allocation at null, thus it's safe to construct // `NonNull`. - unsafe { NonNull { pointer: self.pointer.byte_sub(count) } } + unsafe { NonNull { pointer: self.as_ptr().byte_sub(count) } } } /// Calculates the distance between two pointers within the same allocation. The returned value is in @@ -764,7 +819,7 @@ impl NonNull { T: Sized, { // SAFETY: the caller must uphold the safety contract for `offset_from`. - unsafe { self.pointer.offset_from(origin.pointer) } + unsafe { self.as_ptr().offset_from(origin.as_ptr()) } } /// Calculates the distance between two pointers within the same allocation. The returned value is in @@ -782,7 +837,7 @@ impl NonNull { #[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")] pub const unsafe fn byte_offset_from(self, origin: NonNull) -> isize { // SAFETY: the caller must uphold the safety contract for `byte_offset_from`. - unsafe { self.pointer.byte_offset_from(origin.pointer) } + unsafe { self.as_ptr().byte_offset_from(origin.as_ptr()) } } // N.B. `wrapping_offset``, `wrapping_add`, etc are not implemented because they can wrap to null @@ -857,7 +912,7 @@ impl NonNull { T: Sized, { // SAFETY: the caller must uphold the safety contract for `sub_ptr`. - unsafe { self.pointer.sub_ptr(subtracted.pointer) } + unsafe { self.as_ptr().sub_ptr(subtracted.as_ptr()) } } /// Calculates the distance between two pointers within the same allocation, *where it's known that @@ -876,7 +931,7 @@ impl NonNull { #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] pub const unsafe fn byte_sub_ptr(self, origin: NonNull) -> usize { // SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`. - unsafe { self.pointer.byte_sub_ptr(origin.pointer) } + unsafe { self.as_ptr().byte_sub_ptr(origin.as_ptr()) } } /// Reads the value from `self` without moving it. This leaves the @@ -894,7 +949,7 @@ impl NonNull { T: Sized, { // SAFETY: the caller must uphold the safety contract for `read`. - unsafe { ptr::read(self.pointer) } + unsafe { ptr::read(self.as_ptr()) } } /// Performs a volatile read of the value from `self` without moving it. This @@ -915,7 +970,7 @@ impl NonNull { T: Sized, { // SAFETY: the caller must uphold the safety contract for `read_volatile`. - unsafe { ptr::read_volatile(self.pointer) } + unsafe { ptr::read_volatile(self.as_ptr()) } } /// Reads the value from `self` without moving it. This leaves the @@ -935,7 +990,7 @@ impl NonNull { T: Sized, { // SAFETY: the caller must uphold the safety contract for `read_unaligned`. - unsafe { ptr::read_unaligned(self.pointer) } + unsafe { ptr::read_unaligned(self.as_ptr()) } } /// Copies `count * size_of` bytes from `self` to `dest`. The source @@ -955,7 +1010,7 @@ impl NonNull { T: Sized, { // SAFETY: the caller must uphold the safety contract for `copy`. - unsafe { ptr::copy(self.pointer, dest.as_ptr(), count) } + unsafe { ptr::copy(self.as_ptr(), dest.as_ptr(), count) } } /// Copies `count * size_of` bytes from `self` to `dest`. The source @@ -975,7 +1030,7 @@ impl NonNull { T: Sized, { // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`. - unsafe { ptr::copy_nonoverlapping(self.pointer, dest.as_ptr(), count) } + unsafe { ptr::copy_nonoverlapping(self.as_ptr(), dest.as_ptr(), count) } } /// Copies `count * size_of` bytes from `src` to `self`. The source @@ -995,7 +1050,7 @@ impl NonNull { T: Sized, { // SAFETY: the caller must uphold the safety contract for `copy`. - unsafe { ptr::copy(src.pointer, self.as_ptr(), count) } + unsafe { ptr::copy(src.as_ptr(), self.as_ptr(), count) } } /// Copies `count * size_of` bytes from `src` to `self`. The source @@ -1015,7 +1070,7 @@ impl NonNull { T: Sized, { // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`. - unsafe { ptr::copy_nonoverlapping(src.pointer, self.as_ptr(), count) } + unsafe { ptr::copy_nonoverlapping(src.as_ptr(), self.as_ptr(), count) } } /// Executes the destructor (if any) of the pointed-to value. @@ -1133,7 +1188,7 @@ impl NonNull { /// [`ptr::swap`]: crate::ptr::swap() #[inline(always)] #[stable(feature = "non_null_convenience", since = "1.80.0")] - #[rustc_const_unstable(feature = "const_swap", issue = "83163")] + #[rustc_const_stable(feature = "const_swap", since = "1.85.0")] pub const unsafe fn swap(self, with: NonNull) where T: Sized, @@ -1202,7 +1257,7 @@ impl NonNull { { // SAFETY: `align` has been checked to be a power of 2 above. - unsafe { ptr::align_offset(self.pointer, align) } + unsafe { ptr::align_offset(self.as_ptr(), align) } } } @@ -1230,7 +1285,7 @@ impl NonNull { where T: Sized, { - self.pointer.is_aligned() + self.as_ptr().is_aligned() } /// Returns whether the pointer is aligned to `align`. @@ -1267,7 +1322,7 @@ impl NonNull { #[must_use] #[unstable(feature = "pointer_is_aligned_to", issue = "96284")] pub fn is_aligned_to(self, align: usize) -> bool { - self.pointer.is_aligned_to(align) + self.as_ptr().is_aligned_to(align) } } @@ -1542,6 +1597,9 @@ impl DispatchFromDyn> for NonNull where T: U #[stable(feature = "pin", since = "1.33.0")] unsafe impl PinCoerceUnsized for NonNull {} +#[unstable(feature = "pointer_like_trait", issue = "none")] +impl core::marker::PointerLike for NonNull {} + #[stable(feature = "nonnull", since = "1.25.0")] impl fmt::Debug for NonNull { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/core/src/ptr/unique.rs b/core/src/ptr/unique.rs index a796820a7e468..4810ebe01f9bb 100644 --- a/core/src/ptr/unique.rs +++ b/core/src/ptr/unique.rs @@ -92,7 +92,6 @@ impl Unique { /// Creates a new `Unique` if `ptr` is non-null. #[inline] - #[rustc_const_unstable(feature = "ptr_internals", issue = "none")] pub const fn new(ptr: *mut T) -> Option { if let Some(pointer) = NonNull::new(ptr) { Some(Unique { pointer, _marker: PhantomData }) diff --git a/core/src/result.rs b/core/src/result.rs index b450123c5aa90..92b5cba153166 100644 --- a/core/src/result.rs +++ b/core/src/result.rs @@ -520,7 +520,7 @@ use crate::{convert, fmt, hint}; /// `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]). /// /// See the [module documentation](self) for details. -#[cfg_attr(not(bootstrap), doc(search_unbox))] +#[doc(search_unbox)] #[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] #[must_use = "this `Result` may be an `Err` variant, which should be handled"] #[rustc_diagnostic_item = "Result"] @@ -1065,10 +1065,15 @@ impl Result { /// Returns the contained [`Ok`] value, consuming the `self` value. /// /// Because this function may panic, its use is generally discouraged. - /// Instead, prefer to use pattern matching and handle the [`Err`] - /// case explicitly, or call [`unwrap_or`], [`unwrap_or_else`], or - /// [`unwrap_or_default`]. + /// Panics are meant for unrecoverable errors, and + /// [may abort the entire program][panic-abort]. + /// + /// Instead, prefer to use [the `?` (try) operator][try-operator], or pattern matching + /// to handle the [`Err`] case explicitly, or call [`unwrap_or`], + /// [`unwrap_or_else`], or [`unwrap_or_default`]. /// + /// [panic-abort]: https://doc.rust-lang.org/book/ch09-01-unrecoverable-errors-with-panic.html + /// [try-operator]: https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator /// [`unwrap_or`]: Result::unwrap_or /// [`unwrap_or_else`]: Result::unwrap_or_else /// [`unwrap_or_default`]: Result::unwrap_or_default diff --git a/core/src/slice/ascii.rs b/core/src/slice/ascii.rs index 17ad4fd8f677f..51b25fa40e3d9 100644 --- a/core/src/slice/ascii.rs +++ b/core/src/slice/ascii.rs @@ -3,8 +3,9 @@ use core::ascii::EscapeDefault; use crate::fmt::{self, Write}; +#[cfg(not(all(target_arch = "x86_64", target_feature = "sse2")))] use crate::intrinsics::const_eval_select; -use crate::{ascii, iter, mem, ops}; +use crate::{ascii, iter, ops}; #[cfg(not(test))] impl [u8] { @@ -88,7 +89,7 @@ impl [u8] { /// /// [`to_ascii_uppercase`]: #method.to_ascii_uppercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")] #[inline] pub const fn make_ascii_uppercase(&mut self) { // FIXME(const-hack): We would like to simply iterate using `for` loops but this isn't currently allowed in constant expressions. @@ -110,7 +111,7 @@ impl [u8] { /// /// [`to_ascii_lowercase`]: #method.to_ascii_lowercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")] #[inline] pub const fn make_ascii_lowercase(&mut self) { // FIXME(const-hack): We would like to simply iterate using `for` loops but this isn't currently allowed in constant expressions. @@ -328,14 +329,6 @@ impl<'a> fmt::Debug for EscapeAscii<'a> { } } -/// Returns `true` if any byte in the word `v` is nonascii (>= 128). Snarfed -/// from `../str/mod.rs`, which does something similar for utf8 validation. -#[inline] -const fn contains_nonascii(v: usize) -> bool { - const NONASCII_MASK: usize = usize::repeat_u8(0x80); - (NONASCII_MASK & v) != 0 -} - /// ASCII test *without* the chunk-at-a-time optimizations. /// /// This is carefully structured to produce nice small code -- it's smaller in @@ -366,6 +359,7 @@ pub const fn is_ascii_simple(mut bytes: &[u8]) -> bool { /// /// If any of these loads produces something for which `contains_nonascii` /// (above) returns true, then we know the answer is false. +#[cfg(not(all(target_arch = "x86_64", target_feature = "sse2")))] #[inline] #[rustc_allow_const_fn_unstable(const_eval_select)] // fallback impl has same behavior const fn is_ascii(s: &[u8]) -> bool { @@ -376,7 +370,14 @@ const fn is_ascii(s: &[u8]) -> bool { if const { is_ascii_simple(s) } else { - const USIZE_SIZE: usize = mem::size_of::(); + /// Returns `true` if any byte in the word `v` is nonascii (>= 128). Snarfed + /// from `../str/mod.rs`, which does something similar for utf8 validation. + const fn contains_nonascii(v: usize) -> bool { + const NONASCII_MASK: usize = usize::repeat_u8(0x80); + (NONASCII_MASK & v) != 0 + } + + const USIZE_SIZE: usize = size_of::(); let len = s.len(); let align_offset = s.as_ptr().align_offset(USIZE_SIZE); @@ -386,7 +387,7 @@ const fn is_ascii(s: &[u8]) -> bool { // // We also do this for architectures where `size_of::()` isn't // sufficient alignment for `usize`, because it's a weird edge case. - if len < USIZE_SIZE || len < align_offset || USIZE_SIZE < mem::align_of::() { + if len < USIZE_SIZE || len < align_offset || USIZE_SIZE < align_of::() { return is_ascii_simple(s); } @@ -420,7 +421,7 @@ const fn is_ascii(s: &[u8]) -> bool { // have alignment information it should have given a `usize::MAX` for // `align_offset` earlier, sending things through the scalar path instead of // this one, so this check should pass if it's reachable. - debug_assert!(word_ptr.is_aligned_to(mem::align_of::())); + debug_assert!(word_ptr.is_aligned_to(align_of::())); // Read subsequent words until the last aligned word, excluding the last // aligned word by itself to be done in tail check later, to ensure that @@ -455,3 +456,48 @@ const fn is_ascii(s: &[u8]) -> bool { } ) } + +/// ASCII test optimized to use the `pmovmskb` instruction available on `x86-64` +/// platforms. +/// +/// Other platforms are not likely to benefit from this code structure, so they +/// use SWAR techniques to test for ASCII in `usize`-sized chunks. +#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] +#[inline] +const fn is_ascii(bytes: &[u8]) -> bool { + // Process chunks of 32 bytes at a time in the fast path to enable + // auto-vectorization and use of `pmovmskb`. Two 128-bit vector registers + // can be OR'd together and then the resulting vector can be tested for + // non-ASCII bytes. + const CHUNK_SIZE: usize = 32; + + let mut i = 0; + + while i + CHUNK_SIZE <= bytes.len() { + let chunk_end = i + CHUNK_SIZE; + + // Get LLVM to produce a `pmovmskb` instruction on x86-64 which + // creates a mask from the most significant bit of each byte. + // ASCII bytes are less than 128 (0x80), so their most significant + // bit is unset. + let mut count = 0; + while i < chunk_end { + count += bytes[i].is_ascii() as u8; + i += 1; + } + + // All bytes should be <= 127 so count is equal to chunk size. + if count != CHUNK_SIZE as u8 { + return false; + } + } + + // Process the remaining `bytes.len() % N` bytes. + let mut is_ascii = true; + while i < bytes.len() { + is_ascii &= bytes[i].is_ascii(); + i += 1; + } + + is_ascii +} diff --git a/core/src/slice/iter.rs b/core/src/slice/iter.rs index c5746157d01b2..a687ed7129dc8 100644 --- a/core/src/slice/iter.rs +++ b/core/src/slice/iter.rs @@ -46,13 +46,19 @@ impl<'a, T> IntoIterator for &'a mut [T] { /// Basic usage: /// /// ``` -/// // First, we declare a type which has `iter` method to get the `Iter` struct (`&[usize]` here): +/// // First, we need a slice to call the `iter` method on: /// let slice = &[1, 2, 3]; /// -/// // Then, we iterate over it: +/// // Then we call `iter` on the slice to get the `Iter` iterator, +/// // and iterate over it: /// for element in slice.iter() { /// println!("{element}"); /// } +/// +/// // This for loop actually already works without calling `iter`: +/// for element in slice { +/// println!("{element}"); +/// } /// ``` /// /// [`iter`]: slice::iter @@ -68,7 +74,7 @@ pub struct Iter<'a, T: 'a> { ptr: NonNull, /// For non-ZSTs, the non-null pointer to the past-the-end element. /// - /// For ZSTs, this is `ptr::dangling(len)`. + /// For ZSTs, this is `ptr::without_provenance_mut(len)`. end_or_len: *const T, _marker: PhantomData<&'a T>, } @@ -101,27 +107,29 @@ impl<'a, T> Iter<'a, T> { /// Views the underlying data as a subslice of the original data. /// - /// This has the same lifetime as the original slice, and so the - /// iterator can continue to be used while this exists. - /// /// # Examples /// /// Basic usage: /// /// ``` - /// // First, we declare a type which has the `iter` method to get the `Iter` - /// // struct (`&[usize]` here): + /// // First, we need a slice to call the `iter` method on: /// let slice = &[1, 2, 3]; /// - /// // Then, we get the iterator: + /// // Then we call `iter` on the slice to get the `Iter` iterator: /// let mut iter = slice.iter(); - /// // So if we print what `as_slice` method returns here, we have "[1, 2, 3]": + /// // Here `as_slice` still returns the whole slice, so this prints "[1, 2, 3]": /// println!("{:?}", iter.as_slice()); /// - /// // Next, we move to the second element of the slice: + /// // Now, we call the `next` method to remove the first element from the iterator: /// iter.next(); - /// // Now `as_slice` returns "[2, 3]": + /// // Here the iterator does not contain the first element of the slice any more, + /// // so `as_slice` only returns the last two elements of the slice, + /// // and so this prints "[2, 3]": /// println!("{:?}", iter.as_slice()); + /// + /// // The underlying slice has not been modified and still contains three elements, + /// // so this prints "[1, 2, 3]": + /// println!("{:?}", slice); /// ``` #[must_use] #[stable(feature = "iter_to_slice", since = "1.4.0")] @@ -166,11 +174,11 @@ impl AsRef<[T]> for Iter<'_, T> { /// Basic usage: /// /// ``` -/// // First, we declare a type which has `iter_mut` method to get the `IterMut` -/// // struct (`&[usize]` here): -/// let mut slice = &mut [1, 2, 3]; +/// // First, we need a slice to call the `iter_mut` method on: +/// let slice = &mut [1, 2, 3]; /// -/// // Then, we iterate over it and increment each element value: +/// // Then we call `iter_mut` on the slice to get the `IterMut` iterator, +/// // iterate over it and increment each element value: /// for element in slice.iter_mut() { /// *element += 1; /// } @@ -247,28 +255,21 @@ impl<'a, T> IterMut<'a, T> { /// Basic usage: /// /// ``` - /// // First, we declare a type which has `iter_mut` method to get the `IterMut` - /// // struct (`&[usize]` here): + /// // First, we need a slice to call the `iter_mut` method on: /// let mut slice = &mut [1, 2, 3]; /// - /// { - /// // Then, we get the iterator: - /// let mut iter = slice.iter_mut(); - /// // We move to next element: - /// iter.next(); - /// // So if we print what `into_slice` method returns here, we have "[2, 3]": - /// println!("{:?}", iter.into_slice()); - /// } - /// - /// // Now let's modify a value of the slice: - /// { - /// // First we get back the iterator: - /// let mut iter = slice.iter_mut(); - /// // We change the value of the first element of the slice returned by the `next` method: - /// *iter.next().unwrap() += 1; - /// } - /// // Now slice is "[2, 2, 3]": - /// println!("{slice:?}"); + /// // Then we call `iter_mut` on the slice to get the `IterMut` struct: + /// let mut iter = slice.iter_mut(); + /// // Now, we call the `next` method to remove the first element of the iterator, + /// // unwrap and dereference what we get from `next` and increase its value by 1: + /// *iter.next().unwrap() += 1; + /// // Here the iterator does not contain the first element of the slice any more, + /// // so `into_slice` only returns the last two elements of the slice, + /// // and so this prints "[2, 3]": + /// println!("{:?}", iter.into_slice()); + /// // The underlying slice still contains three elements, but its first element + /// // was increased by 1, so this prints "[2, 2, 3]": + /// println!("{:?}", slice); /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "iter_to_slice", since = "1.4.0")] @@ -281,25 +282,30 @@ impl<'a, T> IterMut<'a, T> { /// Views the underlying data as a subslice of the original data. /// - /// To avoid creating `&mut [T]` references that alias, the returned slice - /// borrows its lifetime from the iterator the method is applied on. - /// /// # Examples /// /// Basic usage: /// /// ``` - /// let mut slice: &mut [usize] = &mut [1, 2, 3]; + /// // First, we need a slice to call the `iter_mut` method on: + /// let slice = &mut [1, 2, 3]; /// - /// // First, we get the iterator: + /// // Then we call `iter_mut` on the slice to get the `IterMut` iterator: /// let mut iter = slice.iter_mut(); - /// // So if we check what the `as_slice` method returns here, we have "[1, 2, 3]": - /// assert_eq!(iter.as_slice(), &[1, 2, 3]); + /// // Here `as_slice` still returns the whole slice, so this prints "[1, 2, 3]": + /// println!("{:?}", iter.as_slice()); /// - /// // Next, we move to the second element of the slice: - /// iter.next(); - /// // Now `as_slice` returns "[2, 3]": - /// assert_eq!(iter.as_slice(), &[2, 3]); + /// // Now, we call the `next` method to remove the first element from the iterator + /// // and increment its value: + /// *iter.next().unwrap() += 1; + /// // Here the iterator does not contain the first element of the slice any more, + /// // so `as_slice` only returns the last two elements of the slice, + /// // and so this prints "[2, 3]": + /// println!("{:?}", iter.as_slice()); + /// + /// // The underlying slice still contains three elements, but its first element + /// // was increased by 1, so this prints "[2, 2, 3]": + /// println!("{:?}", slice); /// ``` #[must_use] #[stable(feature = "slice_iter_mut_as_slice", since = "1.53.0")] @@ -310,9 +316,6 @@ impl<'a, T> IterMut<'a, T> { /// Views the underlying data as a mutable subslice of the original data. /// - /// To avoid creating `&mut [T]` references that alias, the returned slice - /// borrows its lifetime from the iterator the method is applied on. - /// /// # Examples /// /// Basic usage: diff --git a/core/src/slice/memchr.rs b/core/src/slice/memchr.rs index 339adad1b17bf..98db7aaf53321 100644 --- a/core/src/slice/memchr.rs +++ b/core/src/slice/memchr.rs @@ -16,7 +16,6 @@ const USIZE_BYTES: usize = mem::size_of::(); /// bytes where the borrow propagated all the way to the most significant /// bit." #[inline] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_memchr", since = "1.65.0"))] const fn contains_zero_byte(x: usize) -> bool { x.wrapping_sub(LO_USIZE) & !x & HI_USIZE != 0 } @@ -24,7 +23,6 @@ const fn contains_zero_byte(x: usize) -> bool { /// Returns the first index matching the byte `x` in `text`. #[inline] #[must_use] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_memchr", since = "1.65.0"))] pub const fn memchr(x: u8, text: &[u8]) -> Option { // Fast path for small slices. if text.len() < 2 * USIZE_BYTES { @@ -35,7 +33,6 @@ pub const fn memchr(x: u8, text: &[u8]) -> Option { } #[inline] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_memchr", since = "1.65.0"))] const fn memchr_naive(x: u8, text: &[u8]) -> Option { let mut i = 0; @@ -52,7 +49,6 @@ const fn memchr_naive(x: u8, text: &[u8]) -> Option { } #[rustc_allow_const_fn_unstable(const_eval_select)] // fallback impl has same behavior -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_memchr", since = "1.65.0"))] const fn memchr_aligned(x: u8, text: &[u8]) -> Option { // The runtime version behaves the same as the compiletime version, it's // just more optimized. diff --git a/core/src/slice/mod.rs b/core/src/slice/mod.rs index c855f963771ed..5a22110880cc5 100644 --- a/core/src/slice/mod.rs +++ b/core/src/slice/mod.rs @@ -7,13 +7,14 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::cmp::Ordering::{self, Equal, Greater, Less}; -use crate::intrinsics::{exact_div, select_unpredictable, unchecked_sub}; +use crate::intrinsics::{exact_div, unchecked_sub}; use crate::mem::{self, SizedTypeProperties}; use crate::num::NonZero; -use crate::ops::{Bound, OneSidedRange, Range, RangeBounds}; +use crate::ops::{Bound, OneSidedRange, Range, RangeBounds, RangeInclusive}; +use crate::panic::const_panic; use crate::simd::{self, Simd}; use crate::ub_checks::assert_unsafe_precondition; -use crate::{fmt, hint, ptr, slice}; +use crate::{fmt, hint, ptr, range, slice}; #[unstable( feature = "slice_internals", @@ -735,7 +736,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_slice_as_ptr", since = "1.32.0")] #[rustc_never_returns_null_ptr] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[inline(always)] #[must_use] pub const fn as_ptr(&self) -> *const T { @@ -766,7 +767,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] #[rustc_never_returns_null_ptr] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[inline(always)] #[must_use] pub const fn as_mut_ptr(&mut self) -> *mut T { @@ -855,6 +856,42 @@ impl [T] { start..end } + /// Gets a reference to the underlying array. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub const fn as_array(&self) -> Option<&[T; N]> { + if self.len() == N { + let ptr = self.as_ptr() as *const [T; N]; + + // SAFETY: The underlying array of a slice can be reinterpreted as an actual array `[T; N]` if `N` is not greater than the slice's length. + let me = unsafe { &*ptr }; + Some(me) + } else { + None + } + } + + /// Gets a mutable reference to the slice's underlying array. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub const fn as_mut_array(&mut self) -> Option<&mut [T; N]> { + if self.len() == N { + let ptr = self.as_mut_ptr() as *mut [T; N]; + + // SAFETY: The underlying array of a slice can be reinterpreted as an actual array `[T; N]` if `N` is not greater than the slice's length. + let me = unsafe { &mut *ptr }; + Some(me) + } else { + None + } + } + /// Swaps two elements in the slice. /// /// If `a` equals to `b`, it's guaranteed that elements won't change value. @@ -876,7 +913,7 @@ impl [T] { /// assert!(v == ["a", "b", "e", "d", "c"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_swap", issue = "83163")] + #[rustc_const_stable(feature = "const_swap", since = "1.85.0")] #[inline] #[track_caller] pub const fn swap(&mut self, a: usize, b: usize) { @@ -921,7 +958,7 @@ impl [T] { /// [`swap`]: slice::swap /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html #[unstable(feature = "slice_swap_unchecked", issue = "88539")] - #[rustc_const_unstable(feature = "const_swap", issue = "83163")] + #[rustc_const_unstable(feature = "slice_swap_unchecked", issue = "88539")] pub const unsafe fn swap_unchecked(&mut self, a: usize, b: usize) { assert_unsafe_precondition!( check_library_ub, @@ -950,8 +987,9 @@ impl [T] { /// assert!(v == [3, 2, 1]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_slice_reverse", issue = "135120")] #[inline] - pub fn reverse(&mut self) { + pub const fn reverse(&mut self) { let half_len = self.len() / 2; let Range { start, end } = self.as_mut_ptr_range(); @@ -974,7 +1012,7 @@ impl [T] { revswap(front_half, back_half, half_len); #[inline] - fn revswap(a: &mut [T], b: &mut [T], n: usize) { + const fn revswap(a: &mut [T], b: &mut [T], n: usize) { debug_assert!(a.len() == n); debug_assert!(b.len() == n); @@ -982,7 +1020,8 @@ impl [T] { // this check tells LLVM that the indexing below is // in-bounds. Then after inlining -- once the actual // lengths of the slices are known -- it's removed. - let (a, b) = (&mut a[..n], &mut b[..n]); + let (a, _) = a.split_at_mut(n); + let (b, _) = b.split_at_mut(n); let mut i = 0; while i < n { @@ -1039,7 +1078,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `size` is 0. + /// Panics if `size` is zero. /// /// # Examples /// @@ -1095,7 +1134,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `chunk_size` is 0. + /// Panics if `chunk_size` is zero. /// /// # Examples /// @@ -1130,7 +1169,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `chunk_size` is 0. + /// Panics if `chunk_size` is zero. /// /// # Examples /// @@ -1172,7 +1211,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `chunk_size` is 0. + /// Panics if `chunk_size` is zero. /// /// # Examples /// @@ -1211,7 +1250,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `chunk_size` is 0. + /// Panics if `chunk_size` is zero. /// /// # Examples /// @@ -1288,7 +1327,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `N` is 0. This check will most probably get changed to a compile time + /// Panics if `N` is zero. This check will most probably get changed to a compile time /// error before this method gets stabilized. /// /// # Examples @@ -1334,7 +1373,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `N` is 0. This check will most probably get changed to a compile time + /// Panics if `N` is zero. This check will most probably get changed to a compile time /// error before this method gets stabilized. /// /// # Examples @@ -1372,7 +1411,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `N` is 0. This check will most probably get changed to a compile time + /// Panics if `N` is zero. This check will most probably get changed to a compile time /// error before this method gets stabilized. /// /// # Examples @@ -1448,7 +1487,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `N` is 0. This check will most probably get changed to a compile time + /// Panics if `N` is zero. This check will most probably get changed to a compile time /// error before this method gets stabilized. /// /// # Examples @@ -1489,7 +1528,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `N` is 0. This check will most probably get changed to a compile time + /// Panics if `N` is zero. This check will most probably get changed to a compile time /// error before this method gets stabilized. /// /// # Examples @@ -1533,7 +1572,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `N` is 0. This check will most probably get changed to a compile time + /// Panics if `N` is zero. This check will most probably get changed to a compile time /// error before this method gets stabilized. /// /// # Examples @@ -1568,7 +1607,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `N` is 0. This check will most probably get changed to a compile time + /// Panics if `N` is zero. This check will most probably get changed to a compile time /// error before this method gets stabilized. /// /// # Examples @@ -1604,7 +1643,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `chunk_size` is 0. + /// Panics if `chunk_size` is zero. /// /// # Examples /// @@ -1639,7 +1678,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `chunk_size` is 0. + /// Panics if `chunk_size` is zero. /// /// # Examples /// @@ -1682,7 +1721,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `chunk_size` is 0. + /// Panics if `chunk_size` is zero. /// /// # Examples /// @@ -1722,7 +1761,7 @@ impl [T] { /// /// # Panics /// - /// Panics if `chunk_size` is 0. + /// Panics if `chunk_size` is zero. /// /// # Examples /// @@ -1846,23 +1885,23 @@ impl [T] { /// # Examples /// /// ``` - /// let v = [1, 2, 3, 4, 5, 6]; + /// let v = ['a', 'b', 'c']; /// /// { /// let (left, right) = v.split_at(0); /// assert_eq!(left, []); - /// assert_eq!(right, [1, 2, 3, 4, 5, 6]); + /// assert_eq!(right, ['a', 'b', 'c']); /// } /// /// { /// let (left, right) = v.split_at(2); - /// assert_eq!(left, [1, 2]); - /// assert_eq!(right, [3, 4, 5, 6]); + /// assert_eq!(left, ['a', 'b']); + /// assert_eq!(right, ['c']); /// } /// /// { - /// let (left, right) = v.split_at(6); - /// assert_eq!(left, [1, 2, 3, 4, 5, 6]); + /// let (left, right) = v.split_at(3); + /// assert_eq!(left, ['a', 'b', 'c']); /// assert_eq!(right, []); /// } /// ``` @@ -1932,23 +1971,23 @@ impl [T] { /// # Examples /// /// ``` - /// let v = [1, 2, 3, 4, 5, 6]; + /// let v = ['a', 'b', 'c']; /// /// unsafe { /// let (left, right) = v.split_at_unchecked(0); /// assert_eq!(left, []); - /// assert_eq!(right, [1, 2, 3, 4, 5, 6]); + /// assert_eq!(right, ['a', 'b', 'c']); /// } /// /// unsafe { /// let (left, right) = v.split_at_unchecked(2); - /// assert_eq!(left, [1, 2]); - /// assert_eq!(right, [3, 4, 5, 6]); + /// assert_eq!(left, ['a', 'b']); + /// assert_eq!(right, ['c']); /// } /// /// unsafe { - /// let (left, right) = v.split_at_unchecked(6); - /// assert_eq!(left, [1, 2, 3, 4, 5, 6]); + /// let (left, right) = v.split_at_unchecked(3); + /// assert_eq!(left, ['a', 'b', 'c']); /// assert_eq!(right, []); /// } /// ``` @@ -2798,7 +2837,7 @@ impl [T] { // Binary search interacts poorly with branch prediction, so force // the compiler to use conditional moves if supported by the target // architecture. - base = select_unpredictable(cmp == Greater, base, mid); + base = (cmp == Greater).select_unpredictable(base, mid); // This is imprecise in the case where `size` is odd and the // comparison returns Greater: the mid element still gets included @@ -3664,9 +3703,11 @@ impl [T] { /// [`clone_from_slice`]: slice::clone_from_slice /// [`split_at_mut`]: slice::split_at_mut #[doc(alias = "memcpy")] + #[inline] #[stable(feature = "copy_from_slice", since = "1.9.0")] + #[rustc_const_unstable(feature = "const_copy_from_slice", issue = "131415")] #[track_caller] - pub fn copy_from_slice(&mut self, src: &[T]) + pub const fn copy_from_slice(&mut self, src: &[T]) where T: Copy, { @@ -3675,11 +3716,13 @@ impl [T] { #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] - fn len_mismatch_fail(dst_len: usize, src_len: usize) -> ! { - panic!( - "source slice length ({}) does not match destination slice length ({})", - src_len, dst_len, - ); + const fn len_mismatch_fail(dst_len: usize, src_len: usize) -> ! { + const_panic!( + "copy_from_slice: source slice length does not match destination slice length", + "copy_from_slice: source slice length ({src_len}) does not match destination slice length ({dst_len})", + src_len: usize, + dst_len: usize, + ) } if self.len() != src.len() { @@ -4469,6 +4512,12 @@ impl [T] { /// Returns mutable references to many indices at once, without doing any checks. /// + /// An index can be either a `usize`, a [`Range`] or a [`RangeInclusive`]. Note + /// that this method takes an array, so all indices must be of the same type. + /// If passed an array of `usize`s this method gives back an array of mutable references + /// to single elements, while if passed an array of ranges it gives back an array of + /// mutable references to slices. + /// /// For a safe alternative see [`get_many_mut`]. /// /// # Safety @@ -4489,30 +4538,49 @@ impl [T] { /// *b *= 100; /// } /// assert_eq!(x, &[10, 2, 400]); + /// + /// unsafe { + /// let [a, b] = x.get_many_unchecked_mut([0..1, 1..3]); + /// a[0] = 8; + /// b[0] = 88; + /// b[1] = 888; + /// } + /// assert_eq!(x, &[8, 88, 888]); + /// + /// unsafe { + /// let [a, b] = x.get_many_unchecked_mut([1..=2, 0..=0]); + /// a[0] = 11; + /// a[1] = 111; + /// b[0] = 1; + /// } + /// assert_eq!(x, &[1, 11, 111]); /// ``` /// /// [`get_many_mut`]: slice::get_many_mut /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html #[unstable(feature = "get_many_mut", issue = "104642")] #[inline] - pub unsafe fn get_many_unchecked_mut( + pub unsafe fn get_many_unchecked_mut( &mut self, - indices: [usize; N], - ) -> [&mut T; N] { + indices: [I; N], + ) -> [&mut I::Output; N] + where + I: GetManyMutIndex + SliceIndex, + { // NB: This implementation is written as it is because any variation of // `indices.map(|i| self.get_unchecked_mut(i))` would make miri unhappy, // or generate worse code otherwise. This is also why we need to go // through a raw pointer here. let slice: *mut [T] = self; - let mut arr: mem::MaybeUninit<[&mut T; N]> = mem::MaybeUninit::uninit(); + let mut arr: mem::MaybeUninit<[&mut I::Output; N]> = mem::MaybeUninit::uninit(); let arr_ptr = arr.as_mut_ptr(); // SAFETY: We expect `indices` to contain disjunct values that are // in bounds of `self`. unsafe { for i in 0..N { - let idx = *indices.get_unchecked(i); - *(*arr_ptr).get_unchecked_mut(i) = &mut *slice.get_unchecked_mut(idx); + let idx = indices.get_unchecked(i).clone(); + arr_ptr.cast::<&mut I::Output>().add(i).write(&mut *slice.get_unchecked_mut(idx)); } arr.assume_init() } @@ -4520,8 +4588,18 @@ impl [T] { /// Returns mutable references to many indices at once. /// - /// Returns an error if any index is out-of-bounds, or if the same index was - /// passed more than once. + /// An index can be either a `usize`, a [`Range`] or a [`RangeInclusive`]. Note + /// that this method takes an array, so all indices must be of the same type. + /// If passed an array of `usize`s this method gives back an array of mutable references + /// to single elements, while if passed an array of ranges it gives back an array of + /// mutable references to slices. + /// + /// Returns an error if any index is out-of-bounds, or if there are overlapping indices. + /// An empty range is not considered to overlap if it is located at the beginning or at + /// the end of another range, but is considered to overlap if it is located in the middle. + /// + /// This method does a O(n^2) check to check that there are no overlapping indices, so be careful + /// when passing many indices. /// /// # Examples /// @@ -4534,16 +4612,31 @@ impl [T] { /// *b = 612; /// } /// assert_eq!(v, &[413, 2, 612]); + /// + /// if let Ok([a, b]) = v.get_many_mut([0..1, 1..3]) { + /// a[0] = 8; + /// b[0] = 88; + /// b[1] = 888; + /// } + /// assert_eq!(v, &[8, 88, 888]); + /// + /// if let Ok([a, b]) = v.get_many_mut([1..=2, 0..=0]) { + /// a[0] = 11; + /// a[1] = 111; + /// b[0] = 1; + /// } + /// assert_eq!(v, &[1, 11, 111]); /// ``` #[unstable(feature = "get_many_mut", issue = "104642")] #[inline] - pub fn get_many_mut( + pub fn get_many_mut( &mut self, - indices: [usize; N], - ) -> Result<[&mut T; N], GetManyMutError> { - if !get_many_check_valid(&indices, self.len()) { - return Err(GetManyMutError { _private: () }); - } + indices: [I; N], + ) -> Result<[&mut I::Output; N], GetManyMutError> + where + I: GetManyMutIndex + SliceIndex, + { + get_many_check_valid(&indices, self.len())?; // SAFETY: The `get_many_check_valid()` call checked that all indices // are disjunct and in bounds. unsafe { Ok(self.get_many_unchecked_mut(indices)) } @@ -4551,7 +4644,7 @@ impl [T] { /// Returns the index that an element reference points to. /// - /// Returns `None` if `element` does not point within the slice or if it points between elements. + /// Returns `None` if `element` does not point to the start of an element within the slice. /// /// This method is useful for extending slice iterators like [`slice::split`]. /// @@ -4571,9 +4664,9 @@ impl [T] { /// let num = &nums[2]; /// /// assert_eq!(num, &1); - /// assert_eq!(nums.elem_offset(num), Some(2)); + /// assert_eq!(nums.element_offset(num), Some(2)); /// ``` - /// Returning `None` with an in-between element: + /// Returning `None` with an unaligned element: /// ``` /// #![feature(substr_range)] /// @@ -4586,12 +4679,12 @@ impl [T] { /// assert_eq!(ok_elm, &[0, 1]); /// assert_eq!(weird_elm, &[1, 2]); /// - /// assert_eq!(arr.elem_offset(ok_elm), Some(0)); // Points to element 0 - /// assert_eq!(arr.elem_offset(weird_elm), None); // Points between element 0 and 1 + /// assert_eq!(arr.element_offset(ok_elm), Some(0)); // Points to element 0 + /// assert_eq!(arr.element_offset(weird_elm), None); // Points between element 0 and 1 /// ``` #[must_use] #[unstable(feature = "substr_range", issue = "126769")] - pub fn elem_offset(&self, element: &T) -> Option { + pub fn element_offset(&self, element: &T) -> Option { if T::IS_ZST { panic!("elements are zero-sized"); } @@ -4612,7 +4705,8 @@ impl [T] { /// Returns the range of indices that a subslice points to. /// - /// Returns `None` if `subslice` does not point within the slice or if it points between elements. + /// Returns `None` if `subslice` does not point within the slice or if it is not aligned with the + /// elements in the slice. /// /// This method **does not compare elements**. Instead, this method finds the location in the slice that /// `subslice` was obtained from. To find the index of a subslice via comparison, instead use @@ -4730,7 +4824,8 @@ impl [[T; N]] { /// assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]); /// ``` #[stable(feature = "slice_flatten", since = "1.80.0")] - pub fn as_flattened_mut(&mut self) -> &mut [T] { + #[rustc_const_unstable(feature = "const_slice_flatten", issue = "95629")] + pub const fn as_flattened_mut(&mut self) -> &mut [T] { let len = if T::IS_ZST { self.len().checked_mul(N).expect("slice len overflow") } else { @@ -4885,51 +4980,167 @@ impl SlicePattern for [T; N] { /// /// This will do `binomial(N + 1, 2) = N * (N + 1) / 2 = 0, 1, 3, 6, 10, ..` /// comparison operations. -fn get_many_check_valid(indices: &[usize; N], len: usize) -> bool { +#[inline] +fn get_many_check_valid( + indices: &[I; N], + len: usize, +) -> Result<(), GetManyMutError> { // NB: The optimizer should inline the loops into a sequence // of instructions without additional branching. - let mut valid = true; - for (i, &idx) in indices.iter().enumerate() { - valid &= idx < len; - for &idx2 in &indices[..i] { - valid &= idx != idx2; + for (i, idx) in indices.iter().enumerate() { + if !idx.is_in_bounds(len) { + return Err(GetManyMutError::IndexOutOfBounds); + } + for idx2 in &indices[..i] { + if idx.is_overlapping(idx2) { + return Err(GetManyMutError::OverlappingIndices); + } } } - valid + Ok(()) } -/// The error type returned by [`get_many_mut`][`slice::get_many_mut`]. +/// The error type returned by [`get_many_mut`][`slice::get_many_mut`]. /// /// It indicates one of two possible errors: /// - An index is out-of-bounds. -/// - The same index appeared multiple times in the array. +/// - The same index appeared multiple times in the array +/// (or different but overlapping indices when ranges are provided). /// /// # Examples /// /// ``` /// #![feature(get_many_mut)] +/// use std::slice::GetManyMutError; /// /// let v = &mut [1, 2, 3]; -/// assert!(v.get_many_mut([0, 999]).is_err()); -/// assert!(v.get_many_mut([1, 1]).is_err()); +/// assert_eq!(v.get_many_mut([0, 999]), Err(GetManyMutError::IndexOutOfBounds)); +/// assert_eq!(v.get_many_mut([1, 1]), Err(GetManyMutError::OverlappingIndices)); /// ``` #[unstable(feature = "get_many_mut", issue = "104642")] -// NB: The N here is there to be forward-compatible with adding more details -// to the error type at a later point -pub struct GetManyMutError { - _private: (), +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum GetManyMutError { + /// An index provided was out-of-bounds for the slice. + IndexOutOfBounds, + /// Two indices provided were overlapping. + OverlappingIndices, } #[unstable(feature = "get_many_mut", issue = "104642")] -impl fmt::Debug for GetManyMutError { +impl fmt::Display for GetManyMutError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("GetManyMutError").finish_non_exhaustive() + let msg = match self { + GetManyMutError::IndexOutOfBounds => "an index is out of bounds", + GetManyMutError::OverlappingIndices => "there were overlapping indices", + }; + fmt::Display::fmt(msg, f) } } -#[unstable(feature = "get_many_mut", issue = "104642")] -impl fmt::Display for GetManyMutError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt("an index is out of bounds or appeared multiple times in the array", f) +mod private_get_many_mut_index { + use super::{Range, RangeInclusive, range}; + + #[unstable(feature = "get_many_mut_helpers", issue = "none")] + pub trait Sealed {} + + #[unstable(feature = "get_many_mut_helpers", issue = "none")] + impl Sealed for usize {} + #[unstable(feature = "get_many_mut_helpers", issue = "none")] + impl Sealed for Range {} + #[unstable(feature = "get_many_mut_helpers", issue = "none")] + impl Sealed for RangeInclusive {} + #[unstable(feature = "get_many_mut_helpers", issue = "none")] + impl Sealed for range::Range {} + #[unstable(feature = "get_many_mut_helpers", issue = "none")] + impl Sealed for range::RangeInclusive {} +} + +/// A helper trait for `<[T]>::get_many_mut()`. +/// +/// # Safety +/// +/// If `is_in_bounds()` returns `true` and `is_overlapping()` returns `false`, +/// it must be safe to index the slice with the indices. +#[unstable(feature = "get_many_mut_helpers", issue = "none")] +pub unsafe trait GetManyMutIndex: Clone + private_get_many_mut_index::Sealed { + /// Returns `true` if `self` is in bounds for `len` slice elements. + #[unstable(feature = "get_many_mut_helpers", issue = "none")] + fn is_in_bounds(&self, len: usize) -> bool; + + /// Returns `true` if `self` overlaps with `other`. + /// + /// Note that we don't consider zero-length ranges to overlap at the beginning or the end, + /// but do consider them to overlap in the middle. + #[unstable(feature = "get_many_mut_helpers", issue = "none")] + fn is_overlapping(&self, other: &Self) -> bool; +} + +#[unstable(feature = "get_many_mut_helpers", issue = "none")] +// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly. +unsafe impl GetManyMutIndex for usize { + #[inline] + fn is_in_bounds(&self, len: usize) -> bool { + *self < len + } + + #[inline] + fn is_overlapping(&self, other: &Self) -> bool { + *self == *other + } +} + +#[unstable(feature = "get_many_mut_helpers", issue = "none")] +// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly. +unsafe impl GetManyMutIndex for Range { + #[inline] + fn is_in_bounds(&self, len: usize) -> bool { + (self.start <= self.end) & (self.end <= len) + } + + #[inline] + fn is_overlapping(&self, other: &Self) -> bool { + (self.start < other.end) & (other.start < self.end) + } +} + +#[unstable(feature = "get_many_mut_helpers", issue = "none")] +// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly. +unsafe impl GetManyMutIndex for RangeInclusive { + #[inline] + fn is_in_bounds(&self, len: usize) -> bool { + (self.start <= self.end) & (self.end < len) + } + + #[inline] + fn is_overlapping(&self, other: &Self) -> bool { + (self.start <= other.end) & (other.start <= self.end) + } +} + +#[unstable(feature = "get_many_mut_helpers", issue = "none")] +// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly. +unsafe impl GetManyMutIndex for range::Range { + #[inline] + fn is_in_bounds(&self, len: usize) -> bool { + Range::from(*self).is_in_bounds(len) + } + + #[inline] + fn is_overlapping(&self, other: &Self) -> bool { + Range::from(*self).is_overlapping(&Range::from(*other)) + } +} + +#[unstable(feature = "get_many_mut_helpers", issue = "none")] +// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly. +unsafe impl GetManyMutIndex for range::RangeInclusive { + #[inline] + fn is_in_bounds(&self, len: usize) -> bool { + RangeInclusive::from(*self).is_in_bounds(len) + } + + #[inline] + fn is_overlapping(&self, other: &Self) -> bool { + RangeInclusive::from(*self).is_overlapping(&RangeInclusive::from(*other)) } } diff --git a/core/src/str/converts.rs b/core/src/str/converts.rs index c7bae42765f4e..de68f80aa0c8e 100644 --- a/core/src/str/converts.rs +++ b/core/src/str/converts.rs @@ -47,10 +47,11 @@ use crate::{mem, ptr}; /// // some bytes, in a vector /// let sparkle_heart = vec![240, 159, 146, 150]; /// -/// // We know these bytes are valid, so just use `unwrap()`. -/// let sparkle_heart = str::from_utf8(&sparkle_heart).unwrap(); +/// // We can use the ? (try) operator to check if the bytes are valid +/// let sparkle_heart = str::from_utf8(&sparkle_heart)?; /// /// assert_eq!("💖", sparkle_heart); +/// # Ok::<_, str::Utf8Error>(()) /// ``` /// /// Incorrect bytes: diff --git a/core/src/str/lossy.rs b/core/src/str/lossy.rs index e7677c8317a9f..ed2cefc59a51c 100644 --- a/core/src/str/lossy.rs +++ b/core/src/str/lossy.rs @@ -8,7 +8,7 @@ impl [u8] { /// Creates an iterator over the contiguous valid UTF-8 ranges of this /// slice, and the non-UTF-8 fragments in between. /// - /// See the [`Utf8Chunk`] type for documenation of the items yielded by this iterator. + /// See the [`Utf8Chunk`] type for documentation of the items yielded by this iterator. /// /// # Examples /// @@ -150,7 +150,7 @@ impl fmt::Debug for Debug<'_> { /// If you want a simple conversion from UTF-8 byte slices to string slices, /// [`from_utf8`] is easier to use. /// -/// See the [`Utf8Chunk`] type for documenation of the items yielded by this iterator. +/// See the [`Utf8Chunk`] type for documentation of the items yielded by this iterator. /// /// [byteslice]: slice /// [`from_utf8`]: super::from_utf8 diff --git a/core/src/str/mod.rs b/core/src/str/mod.rs index 4629b770cb46d..8a473b398bb5f 100644 --- a/core/src/str/mod.rs +++ b/core/src/str/mod.rs @@ -373,7 +373,7 @@ impl str { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "rustc_str_as_ptr", since = "1.32.0")] #[rustc_never_returns_null_ptr] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[must_use] #[inline(always)] pub const fn as_ptr(&self) -> *const u8 { @@ -391,7 +391,7 @@ impl str { #[stable(feature = "str_as_mut_ptr", since = "1.36.0")] #[rustc_const_stable(feature = "const_str_as_mut", since = "1.83.0")] #[rustc_never_returns_null_ptr] - #[cfg_attr(not(bootstrap), rustc_as_ptr)] + #[rustc_as_ptr] #[must_use] #[inline(always)] pub const fn as_mut_ptr(&mut self) -> *mut u8 { @@ -2503,7 +2503,7 @@ impl str { /// assert_eq!("GRüßE, JüRGEN ❤", s); /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")] #[inline] pub const fn make_ascii_uppercase(&mut self) { // SAFETY: changing ASCII letters only does not invalidate UTF-8. @@ -2531,7 +2531,7 @@ impl str { /// assert_eq!("grÜße, jÜrgen ❤", s); /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")] #[inline] pub const fn make_ascii_lowercase(&mut self) { // SAFETY: changing ASCII letters only does not invalidate UTF-8. diff --git a/core/src/sync/atomic.rs b/core/src/sync/atomic.rs index 7f2a5424787f7..fda26a672990a 100644 --- a/core/src/sync/atomic.rs +++ b/core/src/sync/atomic.rs @@ -86,7 +86,7 @@ //! // This is fine: `join` synchronizes the code in a way such that the atomic //! // store happens-before the non-atomic write. //! let handle = s.spawn(|| atomic.store(1, Ordering::Relaxed)); // atomic store -//! handle.join().unwrap(); // synchronize +//! handle.join().expect("thread won't panic"); // synchronize //! s.spawn(|| unsafe { atomic.as_ptr().write(2) }); // non-atomic write //! }); //! @@ -103,7 +103,7 @@ //! // This is fine: `join` synchronizes the code in a way such that //! // the 1-byte store happens-before the 2-byte store. //! let handle = s.spawn(|| atomic.store(1, Ordering::Relaxed)); -//! handle.join().unwrap(); +//! handle.join().expect("thread won't panic"); //! s.spawn(|| unsafe { //! let differently_sized = transmute::<&AtomicU16, &AtomicU8>(&atomic); //! differently_sized.store(2, Ordering::Relaxed); @@ -469,7 +469,7 @@ impl AtomicBool { /// [valid]: crate::ptr#safety /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses #[stable(feature = "atomic_from_ptr", since = "1.75.0")] - #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")] pub const unsafe fn from_ptr<'a>(ptr: *mut bool) -> &'a AtomicBool { // SAFETY: guaranteed by the caller unsafe { &*ptr.cast() } @@ -1264,7 +1264,7 @@ impl AtomicPtr { /// [valid]: crate::ptr#safety /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses #[stable(feature = "atomic_from_ptr", since = "1.75.0")] - #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")] pub const unsafe fn from_ptr<'a>(ptr: *mut *mut T) -> &'a AtomicPtr { // SAFETY: guaranteed by the caller unsafe { &*ptr.cast() } @@ -2263,7 +2263,7 @@ macro_rules! atomic_int { /// [valid]: crate::ptr#safety /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses #[stable(feature = "atomic_from_ptr", since = "1.75.0")] - #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")] pub const unsafe fn from_ptr<'a>(ptr: *mut $int_type) -> &'a $atomic_type { // SAFETY: guaranteed by the caller unsafe { &*ptr.cast() } diff --git a/core/src/task/wake.rs b/core/src/task/wake.rs index 34673707f010a..4c51ca0a5e437 100644 --- a/core/src/task/wake.rs +++ b/core/src/task/wake.rs @@ -60,7 +60,7 @@ impl RawWaker { RawWaker { data, vtable } } - #[unstable(feature = "noop_waker", issue = "98286")] + #[stable(feature = "noop_waker", since = "1.85.0")] const NOOP: RawWaker = { const VTABLE: RawWakerVTable = RawWakerVTable::new( // Cloning just returns a new no-op raw waker @@ -283,7 +283,6 @@ impl fmt::Debug for Context<'_> { /// # Examples /// ``` /// #![feature(local_waker)] -/// #![feature(noop_waker)] /// use std::task::{ContextBuilder, LocalWaker, Waker, Poll}; /// use std::future::Future; /// @@ -319,12 +318,11 @@ impl<'a> ContextBuilder<'a> { /// Creates a ContextBuilder from a Waker. #[inline] #[unstable(feature = "local_waker", issue = "118959")] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_waker", since = "1.82.0"))] pub const fn from_waker(waker: &'a Waker) -> Self { // SAFETY: LocalWaker is just Waker without thread safety let local_waker = unsafe { transmute(waker) }; Self { - waker: waker, + waker, local_waker, ext: ExtData::None(()), _marker: PhantomData, @@ -373,7 +371,6 @@ impl<'a> ContextBuilder<'a> { /// Builds the `Context`. #[inline] #[unstable(feature = "local_waker", issue = "118959")] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_waker", since = "1.82.0"))] pub const fn build(self) -> Context<'a> { let ContextBuilder { waker, local_waker, ext, _marker, _marker2 } = self; Context { waker, local_waker, ext: AssertUnwindSafe(ext), _marker, _marker2 } @@ -557,8 +554,6 @@ impl Waker { /// # Examples /// /// ``` - /// #![feature(noop_waker)] - /// /// use std::future::Future; /// use std::task; /// @@ -569,7 +564,8 @@ impl Waker { /// ``` #[inline] #[must_use] - #[unstable(feature = "noop_waker", issue = "98286")] + #[stable(feature = "noop_waker", since = "1.85.0")] + #[rustc_const_stable(feature = "noop_waker", since = "1.85.0")] pub const fn noop() -> &'static Waker { const WAKER: &Waker = &Waker { waker: RawWaker::NOOP }; WAKER @@ -852,8 +848,6 @@ impl LocalWaker { /// /// ``` /// #![feature(local_waker)] - /// #![feature(noop_waker)] - /// /// use std::future::Future; /// use std::task::{ContextBuilder, LocalWaker, Waker, Poll}; /// @@ -866,7 +860,7 @@ impl LocalWaker { /// ``` #[inline] #[must_use] - #[unstable(feature = "noop_waker", issue = "98286")] + #[unstable(feature = "local_waker", issue = "118959")] pub const fn noop() -> &'static LocalWaker { const WAKER: &LocalWaker = &LocalWaker { waker: RawWaker::NOOP }; WAKER diff --git a/core/src/time.rs b/core/src/time.rs index 2d93148bac09f..22bd46c567eaa 100644 --- a/core/src/time.rs +++ b/core/src/time.rs @@ -21,6 +21,7 @@ use crate::fmt; use crate::iter::Sum; +use crate::num::niche_types::Nanoseconds; use crate::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; const NANOS_PER_SEC: u32 = 1_000_000_000; @@ -37,24 +38,6 @@ const HOURS_PER_DAY: u64 = 24; #[unstable(feature = "duration_units", issue = "120301")] const DAYS_PER_WEEK: u64 = 7; -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(0)] -#[rustc_layout_scalar_valid_range_end(999_999_999)] -struct Nanoseconds(u32); - -impl Nanoseconds { - // SAFETY: 0 is within the valid range - const ZERO: Self = unsafe { Nanoseconds(0) }; -} - -impl Default for Nanoseconds { - #[inline] - fn default() -> Self { - Self::ZERO - } -} - /// A `Duration` type to represent a span of time, typically used for system /// timeouts. /// @@ -211,14 +194,14 @@ impl Duration { pub const fn new(secs: u64, nanos: u32) -> Duration { if nanos < NANOS_PER_SEC { // SAFETY: nanos < NANOS_PER_SEC, therefore nanos is within the valid range - Duration { secs, nanos: unsafe { Nanoseconds(nanos) } } + Duration { secs, nanos: unsafe { Nanoseconds::new_unchecked(nanos) } } } else { let secs = secs .checked_add((nanos / NANOS_PER_SEC) as u64) .expect("overflow in Duration::new"); let nanos = nanos % NANOS_PER_SEC; // SAFETY: nanos % NANOS_PER_SEC < NANOS_PER_SEC, therefore nanos is within the valid range - Duration { secs, nanos: unsafe { Nanoseconds(nanos) } } + Duration { secs, nanos: unsafe { Nanoseconds::new_unchecked(nanos) } } } } @@ -263,7 +246,7 @@ impl Duration { let subsec_millis = (millis % MILLIS_PER_SEC) as u32; // SAFETY: (x % 1_000) * 1_000_000 < 1_000_000_000 // => x % 1_000 < 1_000 - let subsec_nanos = unsafe { Nanoseconds(subsec_millis * NANOS_PER_MILLI) }; + let subsec_nanos = unsafe { Nanoseconds::new_unchecked(subsec_millis * NANOS_PER_MILLI) }; Duration { secs, nanos: subsec_nanos } } @@ -289,7 +272,7 @@ impl Duration { let subsec_micros = (micros % MICROS_PER_SEC) as u32; // SAFETY: (x % 1_000_000) * 1_000 < 1_000_000_000 // => x % 1_000_000 < 1_000_000 - let subsec_nanos = unsafe { Nanoseconds(subsec_micros * NANOS_PER_MICRO) }; + let subsec_nanos = unsafe { Nanoseconds::new_unchecked(subsec_micros * NANOS_PER_MICRO) }; Duration { secs, nanos: subsec_nanos } } @@ -320,7 +303,7 @@ impl Duration { let secs = nanos / NANOS_PER_SEC; let subsec_nanos = (nanos % NANOS_PER_SEC) as u32; // SAFETY: x % 1_000_000_000 < 1_000_000_000 - let subsec_nanos = unsafe { Nanoseconds(subsec_nanos) }; + let subsec_nanos = unsafe { Nanoseconds::new_unchecked(subsec_nanos) }; Duration { secs, nanos: subsec_nanos } } @@ -458,7 +441,7 @@ impl Duration { #[rustc_const_stable(feature = "duration_zero", since = "1.53.0")] #[inline] pub const fn is_zero(&self) -> bool { - self.secs == 0 && self.nanos.0 == 0 + self.secs == 0 && self.nanos.as_inner() == 0 } /// Returns the number of _whole_ seconds contained by this `Duration`. @@ -509,7 +492,7 @@ impl Duration { #[must_use] #[inline] pub const fn subsec_millis(&self) -> u32 { - self.nanos.0 / NANOS_PER_MILLI + self.nanos.as_inner() / NANOS_PER_MILLI } /// Returns the fractional part of this `Duration`, in whole microseconds. @@ -532,7 +515,7 @@ impl Duration { #[must_use] #[inline] pub const fn subsec_micros(&self) -> u32 { - self.nanos.0 / NANOS_PER_MICRO + self.nanos.as_inner() / NANOS_PER_MICRO } /// Returns the fractional part of this `Duration`, in nanoseconds. @@ -555,7 +538,7 @@ impl Duration { #[must_use] #[inline] pub const fn subsec_nanos(&self) -> u32 { - self.nanos.0 + self.nanos.as_inner() } /// Returns the total number of whole milliseconds contained by this `Duration`. @@ -573,7 +556,8 @@ impl Duration { #[must_use] #[inline] pub const fn as_millis(&self) -> u128 { - self.secs as u128 * MILLIS_PER_SEC as u128 + (self.nanos.0 / NANOS_PER_MILLI) as u128 + self.secs as u128 * MILLIS_PER_SEC as u128 + + (self.nanos.as_inner() / NANOS_PER_MILLI) as u128 } /// Returns the total number of whole microseconds contained by this `Duration`. @@ -591,7 +575,8 @@ impl Duration { #[must_use] #[inline] pub const fn as_micros(&self) -> u128 { - self.secs as u128 * MICROS_PER_SEC as u128 + (self.nanos.0 / NANOS_PER_MICRO) as u128 + self.secs as u128 * MICROS_PER_SEC as u128 + + (self.nanos.as_inner() / NANOS_PER_MICRO) as u128 } /// Returns the total number of nanoseconds contained by this `Duration`. @@ -609,7 +594,7 @@ impl Duration { #[must_use] #[inline] pub const fn as_nanos(&self) -> u128 { - self.secs as u128 * NANOS_PER_SEC as u128 + self.nanos.0 as u128 + self.secs as u128 * NANOS_PER_SEC as u128 + self.nanos.as_inner() as u128 } /// Computes the absolute difference between `self` and `other`. @@ -649,7 +634,7 @@ impl Duration { #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")] pub const fn checked_add(self, rhs: Duration) -> Option { if let Some(mut secs) = self.secs.checked_add(rhs.secs) { - let mut nanos = self.nanos.0 + rhs.nanos.0; + let mut nanos = self.nanos.as_inner() + rhs.nanos.as_inner(); if nanos >= NANOS_PER_SEC { nanos -= NANOS_PER_SEC; if let Some(new_secs) = secs.checked_add(1) { @@ -707,11 +692,11 @@ impl Duration { #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")] pub const fn checked_sub(self, rhs: Duration) -> Option { if let Some(mut secs) = self.secs.checked_sub(rhs.secs) { - let nanos = if self.nanos.0 >= rhs.nanos.0 { - self.nanos.0 - rhs.nanos.0 + let nanos = if self.nanos.as_inner() >= rhs.nanos.as_inner() { + self.nanos.as_inner() - rhs.nanos.as_inner() } else if let Some(sub_secs) = secs.checked_sub(1) { secs = sub_secs; - self.nanos.0 + NANOS_PER_SEC - rhs.nanos.0 + self.nanos.as_inner() + NANOS_PER_SEC - rhs.nanos.as_inner() } else { return None; }; @@ -763,7 +748,7 @@ impl Duration { #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")] pub const fn checked_mul(self, rhs: u32) -> Option { // Multiply nanoseconds as u64, because it cannot overflow that way. - let total_nanos = self.nanos.0 as u64 * rhs as u64; + let total_nanos = self.nanos.as_inner() as u64 * rhs as u64; let extra_secs = total_nanos / (NANOS_PER_SEC as u64); let nanos = (total_nanos % (NANOS_PER_SEC as u64)) as u32; // FIXME(const-hack): use `and_then` once that is possible. @@ -820,7 +805,8 @@ impl Duration { pub const fn checked_div(self, rhs: u32) -> Option { if rhs != 0 { let (secs, extra_secs) = (self.secs / (rhs as u64), self.secs % (rhs as u64)); - let (mut nanos, extra_nanos) = (self.nanos.0 / rhs, self.nanos.0 % rhs); + let (mut nanos, extra_nanos) = + (self.nanos.as_inner() / rhs, self.nanos.as_inner() % rhs); nanos += ((extra_secs * (NANOS_PER_SEC as u64) + extra_nanos as u64) / (rhs as u64)) as u32; debug_assert!(nanos < NANOS_PER_SEC); @@ -846,7 +832,7 @@ impl Duration { #[inline] #[rustc_const_stable(feature = "duration_consts_float", since = "1.83.0")] pub const fn as_secs_f64(&self) -> f64 { - (self.secs as f64) + (self.nanos.0 as f64) / (NANOS_PER_SEC as f64) + (self.secs as f64) + (self.nanos.as_inner() as f64) / (NANOS_PER_SEC as f64) } /// Returns the number of seconds contained by this `Duration` as `f32`. @@ -865,7 +851,7 @@ impl Duration { #[inline] #[rustc_const_stable(feature = "duration_consts_float", since = "1.83.0")] pub const fn as_secs_f32(&self) -> f32 { - (self.secs as f32) + (self.nanos.0 as f32) / (NANOS_PER_SEC as f32) + (self.secs as f32) + (self.nanos.as_inner() as f32) / (NANOS_PER_SEC as f32) } /// Returns the number of milliseconds contained by this `Duration` as `f64`. @@ -885,7 +871,7 @@ impl Duration { #[inline] pub const fn as_millis_f64(&self) -> f64 { (self.secs as f64) * (MILLIS_PER_SEC as f64) - + (self.nanos.0 as f64) / (NANOS_PER_MILLI as f64) + + (self.nanos.as_inner() as f64) / (NANOS_PER_MILLI as f64) } /// Returns the number of milliseconds contained by this `Duration` as `f32`. @@ -905,7 +891,7 @@ impl Duration { #[inline] pub const fn as_millis_f32(&self) -> f32 { (self.secs as f32) * (MILLIS_PER_SEC as f32) - + (self.nanos.0 as f32) / (NANOS_PER_MILLI as f32) + + (self.nanos.as_inner() as f32) / (NANOS_PER_MILLI as f32) } /// Creates a new `Duration` from the specified number of seconds represented @@ -1084,8 +1070,9 @@ impl Duration { #[inline] #[rustc_const_stable(feature = "duration_consts_float", since = "1.83.0")] pub const fn div_duration_f64(self, rhs: Duration) -> f64 { - let self_nanos = (self.secs as f64) * (NANOS_PER_SEC as f64) + (self.nanos.0 as f64); - let rhs_nanos = (rhs.secs as f64) * (NANOS_PER_SEC as f64) + (rhs.nanos.0 as f64); + let self_nanos = + (self.secs as f64) * (NANOS_PER_SEC as f64) + (self.nanos.as_inner() as f64); + let rhs_nanos = (rhs.secs as f64) * (NANOS_PER_SEC as f64) + (rhs.nanos.as_inner() as f64); self_nanos / rhs_nanos } @@ -1105,8 +1092,9 @@ impl Duration { #[inline] #[rustc_const_stable(feature = "duration_consts_float", since = "1.83.0")] pub const fn div_duration_f32(self, rhs: Duration) -> f32 { - let self_nanos = (self.secs as f32) * (NANOS_PER_SEC as f32) + (self.nanos.0 as f32); - let rhs_nanos = (rhs.secs as f32) * (NANOS_PER_SEC as f32) + (rhs.nanos.0 as f32); + let self_nanos = + (self.secs as f32) * (NANOS_PER_SEC as f32) + (self.nanos.as_inner() as f32); + let rhs_nanos = (rhs.secs as f32) * (NANOS_PER_SEC as f32) + (rhs.nanos.as_inner() as f32); self_nanos / rhs_nanos } } @@ -1201,13 +1189,13 @@ macro_rules! sum_durations { for entry in $iter { total_secs = total_secs.checked_add(entry.secs).expect("overflow in iter::sum over durations"); - total_nanos = match total_nanos.checked_add(entry.nanos.0 as u64) { + total_nanos = match total_nanos.checked_add(entry.nanos.as_inner() as u64) { Some(n) => n, None => { total_secs = total_secs .checked_add(total_nanos / NANOS_PER_SEC as u64) .expect("overflow in iter::sum over durations"); - (total_nanos % NANOS_PER_SEC as u64) + entry.nanos.0 as u64 + (total_nanos % NANOS_PER_SEC as u64) + entry.nanos.as_inner() as u64 } }; } @@ -1399,27 +1387,27 @@ impl fmt::Debug for Duration { let prefix = if f.sign_plus() { "+" } else { "" }; if self.secs > 0 { - fmt_decimal(f, self.secs, self.nanos.0, NANOS_PER_SEC / 10, prefix, "s") - } else if self.nanos.0 >= NANOS_PER_MILLI { + fmt_decimal(f, self.secs, self.nanos.as_inner(), NANOS_PER_SEC / 10, prefix, "s") + } else if self.nanos.as_inner() >= NANOS_PER_MILLI { fmt_decimal( f, - (self.nanos.0 / NANOS_PER_MILLI) as u64, - self.nanos.0 % NANOS_PER_MILLI, + (self.nanos.as_inner() / NANOS_PER_MILLI) as u64, + self.nanos.as_inner() % NANOS_PER_MILLI, NANOS_PER_MILLI / 10, prefix, "ms", ) - } else if self.nanos.0 >= NANOS_PER_MICRO { + } else if self.nanos.as_inner() >= NANOS_PER_MICRO { fmt_decimal( f, - (self.nanos.0 / NANOS_PER_MICRO) as u64, - self.nanos.0 % NANOS_PER_MICRO, + (self.nanos.as_inner() / NANOS_PER_MICRO) as u64, + self.nanos.as_inner() % NANOS_PER_MICRO, NANOS_PER_MICRO / 10, prefix, "µs", ) } else { - fmt_decimal(f, self.nanos.0 as u64, 0, 1, prefix, "ns") + fmt_decimal(f, self.nanos.as_inner() as u64, 0, 1, prefix, "ns") } } } diff --git a/core/src/ub_checks.rs b/core/src/ub_checks.rs index 3e6110c9c88a7..b289f6026ffcb 100644 --- a/core/src/ub_checks.rs +++ b/core/src/ub_checks.rs @@ -47,7 +47,6 @@ use crate::intrinsics::{self, const_eval_select}; /// order to call it. Since the precompiled standard library is built with full debuginfo and these /// variables cannot be optimized out in MIR, an innocent-looking `let` can produce enough /// debuginfo to have a measurable compile-time impact on debug builds. -#[cfg_attr(bootstrap, allow_internal_unstable(const_ub_checks))] // permit this to be called in stably-const fn #[macro_export] #[unstable(feature = "ub_checks", issue = "none")] macro_rules! assert_unsafe_precondition { @@ -89,7 +88,6 @@ pub use intrinsics::ub_checks as check_library_ub; /// /// The intention is to not do that when running in the interpreter, as that one has its own /// language UB checks which generally produce better errors. -#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_ub_checks", issue = "none"))] #[inline] #[rustc_allow_const_fn_unstable(const_eval_select)] pub(crate) const fn check_language_ub() -> bool { diff --git a/core/src/unicode/printable.py b/core/src/unicode/printable.py index 4d39ace066c46..260fa9f9e6ad2 100755 --- a/core/src/unicode/printable.py +++ b/core/src/unicode/printable.py @@ -9,7 +9,8 @@ import os import subprocess -NUM_CODEPOINTS=0x110000 +NUM_CODEPOINTS = 0x110000 + def to_ranges(iter): current = None @@ -23,11 +24,15 @@ def to_ranges(iter): if current is not None: yield tuple(current) + def get_escaped(codepoints): for c in codepoints: - if (c.class_ or "Cn") in "Cc Cf Cs Co Cn Zl Zp Zs".split() and c.value != ord(' '): + if (c.class_ or "Cn") in "Cc Cf Cs Co Cn Zl Zp Zs".split() and c.value != ord( + " " + ): yield c.value + def get_file(f): try: return open(os.path.basename(f)) @@ -35,7 +40,9 @@ def get_file(f): subprocess.run(["curl", "-O", f], check=True) return open(os.path.basename(f)) -Codepoint = namedtuple('Codepoint', 'value class_') + +Codepoint = namedtuple("Codepoint", "value class_") + def get_codepoints(f): r = csv.reader(f, delimiter=";") @@ -66,13 +73,14 @@ def get_codepoints(f): for c in range(prev_codepoint + 1, NUM_CODEPOINTS): yield Codepoint(c, None) + def compress_singletons(singletons): - uppers = [] # (upper, # items in lowers) + uppers = [] # (upper, # items in lowers) lowers = [] for i in singletons: upper = i >> 8 - lower = i & 0xff + lower = i & 0xFF if len(uppers) == 0 or uppers[-1][0] != upper: uppers.append((upper, 1)) else: @@ -82,10 +90,11 @@ def compress_singletons(singletons): return uppers, lowers + def compress_normal(normal): # lengths 0x00..0x7f are encoded as 00, 01, ..., 7e, 7f # lengths 0x80..0x7fff are encoded as 80 80, 80 81, ..., ff fe, ff ff - compressed = [] # [truelen, (truelenaux), falselen, (falselenaux)] + compressed = [] # [truelen, (truelenaux), falselen, (falselenaux)] prev_start = 0 for start, count in normal: @@ -95,21 +104,22 @@ def compress_normal(normal): assert truelen < 0x8000 and falselen < 0x8000 entry = [] - if truelen > 0x7f: + if truelen > 0x7F: entry.append(0x80 | (truelen >> 8)) - entry.append(truelen & 0xff) + entry.append(truelen & 0xFF) else: - entry.append(truelen & 0x7f) - if falselen > 0x7f: + entry.append(truelen & 0x7F) + if falselen > 0x7F: entry.append(0x80 | (falselen >> 8)) - entry.append(falselen & 0xff) + entry.append(falselen & 0xFF) else: - entry.append(falselen & 0x7f) + entry.append(falselen & 0x7F) compressed.append(entry) return compressed + def print_singletons(uppers, lowers, uppersname, lowersname): print("#[rustfmt::skip]") print("const {}: &[(u8, u8)] = &[".format(uppersname)) @@ -119,9 +129,12 @@ def print_singletons(uppers, lowers, uppersname, lowersname): print("#[rustfmt::skip]") print("const {}: &[u8] = &[".format(lowersname)) for i in range(0, len(lowers), 8): - print(" {}".format(" ".join("{:#04x},".format(x) for x in lowers[i:i+8]))) + print( + " {}".format(" ".join("{:#04x},".format(x) for x in lowers[i : i + 8])) + ) print("];") + def print_normal(normal, normalname): print("#[rustfmt::skip]") print("const {}: &[u8] = &[".format(normalname)) @@ -129,12 +142,13 @@ def print_normal(normal, normalname): print(" {}".format(" ".join("{:#04x},".format(i) for i in v))) print("];") + def main(): file = get_file("https://www.unicode.org/Public/UNIDATA/UnicodeData.txt") codepoints = get_codepoints(file) - CUTOFF=0x10000 + CUTOFF = 0x10000 singletons0 = [] singletons1 = [] normal0 = [] @@ -234,10 +248,11 @@ def main(): }\ """) print() - print_singletons(singletons0u, singletons0l, 'SINGLETONS0U', 'SINGLETONS0L') - print_singletons(singletons1u, singletons1l, 'SINGLETONS1U', 'SINGLETONS1L') - print_normal(normal0, 'NORMAL0') - print_normal(normal1, 'NORMAL1') + print_singletons(singletons0u, singletons0l, "SINGLETONS0U", "SINGLETONS0L") + print_singletons(singletons1u, singletons1l, "SINGLETONS1U", "SINGLETONS1L") + print_normal(normal0, "NORMAL0") + print_normal(normal1, "NORMAL1") + -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/core/src/unicode/unicode_data.rs b/core/src/unicode/unicode_data.rs index 7f4826402eb53..4655d35e9c437 100644 --- a/core/src/unicode/unicode_data.rs +++ b/core/src/unicode/unicode_data.rs @@ -1,7 +1,6 @@ ///! This file is generated by `./x run src/tools/unicode-table-generator`; do not edit manually! #[inline(always)] -#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_unicode_case_lookup", since = "1.84.0"))] const fn bitset_search< const N: usize, const CHUNK_SIZE: usize, @@ -424,7 +423,6 @@ pub mod lowercase { (5, 187), (6, 78), (7, 132), ]; - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_unicode_case_lookup", since = "1.84.0"))] pub const fn lookup(c: char) -> bool { super::bitset_search( c as u32, @@ -549,7 +547,6 @@ pub mod uppercase { (2, 146), (2, 20), (3, 146), (3, 140), (3, 134), (4, 178), (4, 171), ]; - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_unicode_case_lookup", since = "1.84.0"))] pub const fn lookup(c: char) -> bool { super::bitset_search( c as u32, diff --git a/core/src/unsafe_binder.rs b/core/src/unsafe_binder.rs new file mode 100644 index 0000000000000..98f53e07d9d8d --- /dev/null +++ b/core/src/unsafe_binder.rs @@ -0,0 +1,25 @@ +//! Operators used to turn types into unsafe binders and back. + +/// Unwrap an unsafe binder into its underlying type. +#[allow_internal_unstable(builtin_syntax)] +#[unstable(feature = "unsafe_binders", issue = "130516")] +pub macro unwrap_binder { + ($expr:expr) => { + builtin # unwrap_binder ( $expr ) + }, + ($expr:expr ; $ty:ty) => { + builtin # unwrap_binder ( $expr, $ty ) + }, +} + +/// Wrap a type into an unsafe binder. +#[allow_internal_unstable(builtin_syntax)] +#[unstable(feature = "unsafe_binders", issue = "130516")] +pub macro wrap_binder { + ($expr:expr) => { + builtin # wrap_binder ( $expr ) + }, + ($expr:expr ; $ty:ty) => { + builtin # wrap_binder ( $expr, $ty ) + }, +} diff --git a/core/tests/fmt/mod.rs b/core/tests/fmt/mod.rs index 704d246139947..2c93a9bc80db9 100644 --- a/core/tests/fmt/mod.rs +++ b/core/tests/fmt/mod.rs @@ -43,3 +43,34 @@ fn pad_integral_resets() { assert_eq!(format!("{Bar:<03}"), "1 0051 "); } + +#[test] +fn test_maybe_uninit_short() { + // Ensure that the trimmed `MaybeUninit` Debug implementation doesn't break + let x = core::mem::MaybeUninit::new(0u32); + assert_eq!(format!("{x:?}"), "MaybeUninit"); +} + +#[test] +fn formatting_options_flags() { + use core::fmt::*; + for sign in [None, Some(Sign::Plus), Some(Sign::Minus)] { + for alternate in [true, false] { + for sign_aware_zero_pad in [true, false] { + for debug_as_hex in [None, Some(DebugAsHex::Lower), Some(DebugAsHex::Upper)] { + let mut formatting_options = FormattingOptions::new(); + formatting_options + .sign(sign) + .sign_aware_zero_pad(sign_aware_zero_pad) + .alternate(alternate) + .debug_as_hex(debug_as_hex); + + assert_eq!(formatting_options.get_sign(), sign); + assert_eq!(formatting_options.get_alternate(), alternate); + assert_eq!(formatting_options.get_sign_aware_zero_pad(), sign_aware_zero_pad); + assert_eq!(formatting_options.get_debug_as_hex(), debug_as_hex); + } + } + } + } +} diff --git a/core/tests/hash/mod.rs b/core/tests/hash/mod.rs index bf91e9e5df0e2..9f14995f73fe2 100644 --- a/core/tests/hash/mod.rs +++ b/core/tests/hash/mod.rs @@ -4,16 +4,11 @@ use std::hash::{BuildHasher, Hash, Hasher}; use std::ptr; use std::rc::Rc; +#[derive(Default)] struct MyHasher { hash: u64, } -impl Default for MyHasher { - fn default() -> MyHasher { - MyHasher { hash: 0 } - } -} - impl Hasher for MyHasher { fn write(&mut self, buf: &[u8]) { for byte in buf { @@ -107,6 +102,8 @@ fn test_writer_hasher() { struct Custom { hash: u64, } + +#[derive(Default)] struct CustomHasher { output: u64, } @@ -123,12 +120,6 @@ impl Hasher for CustomHasher { } } -impl Default for CustomHasher { - fn default() -> CustomHasher { - CustomHasher { output: 0 } - } -} - impl Hash for Custom { fn hash(&self, state: &mut H) { state.write_u64(self.hash); diff --git a/core/tests/intrinsics.rs b/core/tests/intrinsics.rs index 8b731cf5b25d1..744a6a0d2dd8f 100644 --- a/core/tests/intrinsics.rs +++ b/core/tests/intrinsics.rs @@ -125,3 +125,71 @@ fn test_three_way_compare_in_const_contexts() { assert_eq!(SIGNED_EQUAL, Equal); assert_eq!(SIGNED_GREATER, Greater); } + +fn fallback_cma( + a: T, + b: T, + c: T, + d: T, +) -> (T::Unsigned, T) { + a.carrying_mul_add(b, c, d) +} + +#[test] +fn carrying_mul_add_fallback_u32() { + let r = fallback_cma::(0x9e37_79b9, 0x7f4a_7c15, 0xf39c_c060, 0x5ced_c834); + assert_eq!(r, (0x2087_20c1, 0x4eab_8e1d)); + let r = fallback_cma::(0x1082_276b, 0xf3a2_7251, 0xf86c_6a11, 0xd0c1_8e95); + assert_eq!(r, (0x7aa0_1781, 0x0fb6_0528)); +} + +#[test] +fn carrying_mul_add_fallback_i32() { + let r = fallback_cma::(-1, -1, -1, -1); + assert_eq!(r, (u32::MAX, -1)); + let r = fallback_cma::(1, -1, 1, 1); + assert_eq!(r, (1, 0)); +} + +#[test] +fn carrying_mul_add_fallback_u128() { + assert_eq!(fallback_cma::(u128::MAX, u128::MAX, 0, 0), (1, u128::MAX - 1)); + assert_eq!(fallback_cma::(1, 1, 1, 1), (3, 0)); + assert_eq!(fallback_cma::(0, 0, u128::MAX, u128::MAX), (u128::MAX - 1, 1)); + assert_eq!( + fallback_cma::(u128::MAX, u128::MAX, u128::MAX, u128::MAX), + (u128::MAX, u128::MAX), + ); + + let r = fallback_cma::( + 0x243f6a8885a308d313198a2e03707344, + 0xa4093822299f31d0082efa98ec4e6c89, + 0x452821e638d01377be5466cf34e90c6c, + 0xc0ac29b7c97c50dd3f84d5b5b5470917, + ); + assert_eq!(r, (0x8050ec20ed554e40338d277e00b674e7, 0x1739ee6cea07da409182d003859b59d8)); + let r = fallback_cma::( + 0x9216d5d98979fb1bd1310ba698dfb5ac, + 0x2ffd72dbd01adfb7b8e1afed6a267e96, + 0xba7c9045f12c7f9924a19947b3916cf7, + 0x0801f2e2858efc16636920d871574e69, + ); + assert_eq!(r, (0x185525545fdb2fefb502a3a602efd628, 0x1b62d35fe3bff6b566f99667ef7ebfd6)); +} + +#[test] +fn carrying_mul_add_fallback_i128() { + assert_eq!(fallback_cma::(-1, -1, 0, 0), (1, 0)); + let r = fallback_cma::(-1, -1, -1, -1); + assert_eq!(r, (u128::MAX, -1)); + let r = fallback_cma::(1, -1, 1, 1); + assert_eq!(r, (1, 0)); + assert_eq!( + fallback_cma::(i128::MAX, i128::MAX, i128::MAX, i128::MAX), + (u128::MAX, i128::MAX / 2), + ); + assert_eq!( + fallback_cma::(i128::MIN, i128::MIN, i128::MAX, i128::MAX), + (u128::MAX - 1, -(i128::MIN / 2)), + ); +} diff --git a/core/tests/iter/adapters/take.rs b/core/tests/iter/adapters/take.rs index 65a8a93b4a916..b932059afec8a 100644 --- a/core/tests/iter/adapters/take.rs +++ b/core/tests/iter/adapters/take.rs @@ -255,7 +255,7 @@ fn test_reverse_on_zip() { let zipped_iter = vec_1.iter().zip(core::iter::repeat(0).take(20)); - // Cannot call rev here for automatic reversed zip constuction + // Cannot call rev here for automatic reversed zip construction for (&one, zero) in zipped_iter.rev() { assert_eq!((1, 0), (one, zero)); } diff --git a/core/tests/iter/traits/iterator.rs b/core/tests/iter/traits/iterator.rs index 93ef9c0812b16..e31d2e15b6d7e 100644 --- a/core/tests/iter/traits/iterator.rs +++ b/core/tests/iter/traits/iterator.rs @@ -617,6 +617,31 @@ fn test_next_chunk() { assert_eq!(it.next_chunk::<0>().unwrap(), []); } +#[test] +fn test_collect_into_tuples() { + let a = vec![(1, 2, 3), (4, 5, 6), (7, 8, 9)]; + let b = vec![1, 4, 7]; + let c = vec![2, 5, 8]; + let d = vec![3, 6, 9]; + let mut e = (Vec::new(), Vec::new(), Vec::new()); + a.iter().cloned().collect_into(&mut e); + assert!(e.0 == b); + assert!(e.1 == c); + assert!(e.2 == d); +} + +#[test] +fn test_collect_for_tuples() { + let a = vec![(1, 2, 3), (4, 5, 6), (7, 8, 9)]; + let b = vec![1, 4, 7]; + let c = vec![2, 5, 8]; + let d = vec![3, 6, 9]; + let e: (Vec<_>, Vec<_>, Vec<_>) = a.into_iter().collect(); + assert!(e.0 == b); + assert!(e.1 == c); + assert!(e.2 == d); +} + // just tests by whether or not this compiles fn _empty_impl_all_auto_traits() { use std::panic::{RefUnwindSafe, UnwindSafe}; diff --git a/core/tests/lib.rs b/core/tests/lib.rs index f7825571cd7a8..18feee9fb2545 100644 --- a/core/tests/lib.rs +++ b/core/tests/lib.rs @@ -1,7 +1,4 @@ // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(const_three_way_compare))] -#![cfg_attr(bootstrap, feature(strict_provenance))] -#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))] #![cfg_attr(target_has_atomic = "128", feature(integer_atomics))] #![cfg_attr(test, feature(cfg_match))] #![feature(alloc_layout_extra)] @@ -16,13 +13,12 @@ #![feature(bigint_helper_methods)] #![feature(cell_update)] #![feature(clone_to_uninit)] -#![feature(const_align_of_val_raw)] #![feature(const_black_box)] #![feature(const_eval_select)] -#![feature(const_heap)] -#![feature(const_nonnull_new)] +#![feature(const_swap_nonoverlapping)] #![feature(const_trait_impl)] #![feature(core_intrinsics)] +#![feature(core_intrinsics_fallbacks)] #![feature(core_io_borrowed_buf)] #![feature(core_private_bignum)] #![feature(core_private_diy_float)] @@ -35,6 +31,7 @@ #![feature(float_minimum_maximum)] #![feature(flt2dec)] #![feature(fmt_internals)] +#![feature(formatting_options)] #![feature(freeze)] #![feature(future_join)] #![feature(generic_assert_internals)] @@ -65,8 +62,7 @@ #![feature(maybe_uninit_write_slice)] #![feature(min_specialization)] #![feature(never_type)] -#![feature(noop_waker)] -#![feature(num_midpoint)] +#![feature(num_midpoint_signed)] #![feature(numfmt)] #![feature(pattern)] #![feature(pointer_is_aligned_to)] @@ -83,6 +79,7 @@ #![feature(step_trait)] #![feature(str_internals)] #![feature(strict_provenance_atomic_ptr)] +#![feature(strict_provenance_lints)] #![feature(test)] #![feature(trait_upcasting)] #![feature(trusted_len)] @@ -101,10 +98,13 @@ /// Version of `assert_matches` that ignores fancy runtime printing in const context and uses structural equality. macro_rules! assert_eq_const_safe { + ($left:expr, $right:expr) => { + assert_eq_const_safe!($left, $right, concat!(stringify!($left), " == ", stringify!($right))); + }; ($left:expr, $right:expr$(, $($arg:tt)+)?) => { { fn runtime() { - assert_eq!($left, $right, $($arg)*); + assert_eq!($left, $right, $($($arg)*),*); } const fn compiletime() { assert!(matches!($left, const { $right })); diff --git a/core/tests/mem.rs b/core/tests/mem.rs index f3b4387f6a898..1b5c5fc82a69d 100644 --- a/core/tests/mem.rs +++ b/core/tests/mem.rs @@ -200,60 +200,60 @@ fn uninit_array_assume_init() { } #[test] -fn uninit_write_slice() { +fn uninit_write_copy_of_slice() { let mut dst = [MaybeUninit::new(255); 64]; let src = [0; 64]; - assert_eq!(MaybeUninit::copy_from_slice(&mut dst, &src), &src); + assert_eq!(dst.write_copy_of_slice(&src), &src); } #[test] #[should_panic(expected = "source slice length (32) does not match destination slice length (64)")] -fn uninit_write_slice_panic_lt() { +fn uninit_write_copy_of_slice_panic_lt() { let mut dst = [MaybeUninit::uninit(); 64]; let src = [0; 32]; - MaybeUninit::copy_from_slice(&mut dst, &src); + dst.write_copy_of_slice(&src); } #[test] #[should_panic(expected = "source slice length (128) does not match destination slice length (64)")] -fn uninit_write_slice_panic_gt() { +fn uninit_write_copy_of_slice_panic_gt() { let mut dst = [MaybeUninit::uninit(); 64]; let src = [0; 128]; - MaybeUninit::copy_from_slice(&mut dst, &src); + dst.write_copy_of_slice(&src); } #[test] -fn uninit_clone_from_slice() { +fn uninit_write_clone_of_slice() { let mut dst = [MaybeUninit::new(255); 64]; let src = [0; 64]; - assert_eq!(MaybeUninit::clone_from_slice(&mut dst, &src), &src); + assert_eq!(dst.write_clone_of_slice(&src), &src); } #[test] #[should_panic(expected = "destination and source slices have different lengths")] -fn uninit_write_slice_cloned_panic_lt() { +fn uninit_write_clone_of_slice_panic_lt() { let mut dst = [MaybeUninit::uninit(); 64]; let src = [0; 32]; - MaybeUninit::clone_from_slice(&mut dst, &src); + dst.write_clone_of_slice(&src); } #[test] #[should_panic(expected = "destination and source slices have different lengths")] -fn uninit_write_slice_cloned_panic_gt() { +fn uninit_write_clone_of_slice_panic_gt() { let mut dst = [MaybeUninit::uninit(); 64]; let src = [0; 128]; - MaybeUninit::clone_from_slice(&mut dst, &src); + dst.write_clone_of_slice(&src); } #[test] #[cfg(panic = "unwind")] -fn uninit_write_slice_cloned_mid_panic() { +fn uninit_write_clone_of_slice_mid_panic() { use std::panic; enum IncrementOrPanic { @@ -289,7 +289,7 @@ fn uninit_write_slice_cloned_mid_panic() { ]; let err = panic::catch_unwind(panic::AssertUnwindSafe(|| { - MaybeUninit::clone_from_slice(&mut dst, &src); + dst.write_clone_of_slice(&src); })); drop(src); @@ -317,11 +317,11 @@ impl Drop for Bomb { } #[test] -fn uninit_write_slice_cloned_no_drop() { +fn uninit_write_clone_of_slice_no_drop() { let mut dst = [MaybeUninit::uninit()]; let src = [Bomb]; - MaybeUninit::clone_from_slice(&mut dst, &src); + dst.write_clone_of_slice(&src); forget(src); } diff --git a/core/tests/num/i128.rs b/core/tests/num/i128.rs index 1ddd20f33d0b1..745fee05164c9 100644 --- a/core/tests/num/i128.rs +++ b/core/tests/num/i128.rs @@ -1 +1 @@ -int_module!(i128); +int_module!(i128, u128); diff --git a/core/tests/num/i16.rs b/core/tests/num/i16.rs index c7aa9fff964ed..6acb8371b87d8 100644 --- a/core/tests/num/i16.rs +++ b/core/tests/num/i16.rs @@ -1 +1 @@ -int_module!(i16); +int_module!(i16, u16); diff --git a/core/tests/num/i32.rs b/core/tests/num/i32.rs index efd5b1596a80d..38d5071f71d6c 100644 --- a/core/tests/num/i32.rs +++ b/core/tests/num/i32.rs @@ -1,4 +1,4 @@ -int_module!(i32); +int_module!(i32, u32); #[test] fn test_arith_operation() { diff --git a/core/tests/num/i64.rs b/core/tests/num/i64.rs index 93d23c10adf7e..f8dd5f9be7fe2 100644 --- a/core/tests/num/i64.rs +++ b/core/tests/num/i64.rs @@ -1 +1 @@ -int_module!(i64); +int_module!(i64, u64); diff --git a/core/tests/num/i8.rs b/core/tests/num/i8.rs index 887d4f17d25ff..a10906618c937 100644 --- a/core/tests/num/i8.rs +++ b/core/tests/num/i8.rs @@ -1 +1 @@ -int_module!(i8); +int_module!(i8, u8); diff --git a/core/tests/num/int_macros.rs b/core/tests/num/int_macros.rs index 474d57049ab65..f13b836378b9e 100644 --- a/core/tests/num/int_macros.rs +++ b/core/tests/num/int_macros.rs @@ -1,8 +1,10 @@ macro_rules! int_module { - ($T:ident) => { + ($T:ident, $U:ident) => { use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr}; use core::$T::*; + const UMAX: $U = $U::MAX; + use crate::num; #[test] @@ -355,6 +357,102 @@ macro_rules! int_module { assert_eq_const_safe!((0 as $T).borrowing_sub(MIN, true), (MAX, false)); } + fn test_widening_mul() { + assert_eq_const_safe!(MAX.widening_mul(MAX), (1, MAX / 2)); + assert_eq_const_safe!(MIN.widening_mul(MAX), (MIN as $U, MIN / 2)); + assert_eq_const_safe!(MIN.widening_mul(MIN), (0, MAX / 2 + 1)); + } + + fn test_carrying_mul() { + assert_eq_const_safe!(MAX.carrying_mul(MAX, 0), (1, MAX / 2)); + assert_eq_const_safe!( + MAX.carrying_mul(MAX, MAX), + (UMAX / 2 + 1, MAX / 2) + ); + assert_eq_const_safe!( + MAX.carrying_mul(MAX, MIN), + (UMAX / 2 + 2, MAX / 2 - 1) + ); + assert_eq_const_safe!(MIN.carrying_mul(MAX, 0), (MIN as $U, MIN / 2)); + assert_eq_const_safe!(MIN.carrying_mul(MAX, MAX), (UMAX, MIN / 2)); + assert_eq_const_safe!(MIN.carrying_mul(MAX, MIN), (0, MIN / 2)); + assert_eq_const_safe!(MIN.carrying_mul(MIN, 0), (0, MAX / 2 + 1)); + assert_eq_const_safe!( + MIN.carrying_mul(MIN, MAX), + (UMAX / 2, MAX / 2 + 1) + ); + assert_eq_const_safe!( + MIN.carrying_mul(MIN, MIN), + (UMAX / 2 + 1, MAX / 2) + ); + } + + fn test_carrying_mul_add() { + assert_eq_const_safe!(MAX.carrying_mul_add(MAX, 0, 0), (1, MAX / 2)); + assert_eq_const_safe!( + MAX.carrying_mul_add(MAX, MAX, 0), + (UMAX / 2 + 1, MAX / 2) + ); + assert_eq_const_safe!( + MAX.carrying_mul_add(MAX, MIN, 0), + (UMAX / 2 + 2, MAX / 2 - 1) + ); + assert_eq_const_safe!( + MAX.carrying_mul_add(MAX, MAX, MAX), + (UMAX, MAX / 2) + ); + assert_eq_const_safe!( + MAX.carrying_mul_add(MAX, MAX, MIN), + (0, MAX / 2) + ); + assert_eq_const_safe!( + MAX.carrying_mul_add(MAX, MIN, MIN), + (1, MAX / 2 - 1) + ); + assert_eq_const_safe!( + MIN.carrying_mul_add(MAX, 0, 0), + (MIN as $U, MIN / 2) + ); + assert_eq_const_safe!( + MIN.carrying_mul_add(MAX, MAX, 0), + (UMAX, MIN / 2) + ); + assert_eq_const_safe!(MIN.carrying_mul_add(MAX, MIN, 0), (0, MIN / 2)); + assert_eq_const_safe!( + MIN.carrying_mul_add(MAX, MAX, MAX), + (UMAX / 2 - 1, MIN / 2 + 1) + ); + assert_eq_const_safe!( + MIN.carrying_mul_add(MAX, MAX, MIN), + (UMAX / 2, MIN / 2) + ); + assert_eq_const_safe!( + MIN.carrying_mul_add(MAX, MIN, MIN), + (UMAX / 2 + 1, MIN / 2 - 1) + ); + assert_eq_const_safe!(MIN.carrying_mul_add(MIN, 0, 0), (0, MAX / 2 + 1)); + assert_eq_const_safe!( + MIN.carrying_mul_add(MIN, MAX, 0), + (UMAX / 2, MAX / 2 + 1) + ); + assert_eq_const_safe!( + MIN.carrying_mul_add(MIN, MIN, 0), + (UMAX / 2 + 1, MAX / 2) + ); + assert_eq_const_safe!( + MIN.carrying_mul_add(MIN, MAX, MAX), + (UMAX - 1, MAX / 2 + 1) + ); + assert_eq_const_safe!( + MIN.carrying_mul_add(MIN, MAX, MIN), + (UMAX, MAX / 2) + ); + assert_eq_const_safe!( + MIN.carrying_mul_add(MIN, MIN, MIN), + (0, MAX / 2) + ); + } + fn test_midpoint() { assert_eq_const_safe!(<$T>::midpoint(1, 3), 2); assert_eq_const_safe!(<$T>::midpoint(3, 1), 2); diff --git a/core/tests/num/uint_macros.rs b/core/tests/num/uint_macros.rs index ad8e48491e829..99a2d4cd462b1 100644 --- a/core/tests/num/uint_macros.rs +++ b/core/tests/num/uint_macros.rs @@ -277,6 +277,21 @@ macro_rules! uint_module { assert_eq_const_safe!($T::MAX.borrowing_sub($T::MAX, true), ($T::MAX, true)); } + fn test_widening_mul() { + assert_eq_const_safe!($T::MAX.widening_mul($T::MAX), (1, $T::MAX - 1)); + } + + fn test_carrying_mul() { + assert_eq_const_safe!($T::MAX.carrying_mul($T::MAX, 0), (1, $T::MAX - 1)); + assert_eq_const_safe!($T::MAX.carrying_mul($T::MAX, $T::MAX), (0, $T::MAX)); + } + + fn test_carrying_mul_add() { + assert_eq_const_safe!($T::MAX.carrying_mul_add($T::MAX, 0, 0), (1, $T::MAX - 1)); + assert_eq_const_safe!($T::MAX.carrying_mul_add($T::MAX, $T::MAX, 0), (0, $T::MAX)); + assert_eq_const_safe!($T::MAX.carrying_mul_add($T::MAX, $T::MAX, $T::MAX), ($T::MAX, $T::MAX)); + } + fn test_midpoint() { assert_eq_const_safe!(<$T>::midpoint(1, 3), 2); assert_eq_const_safe!(<$T>::midpoint(3, 1), 2); diff --git a/core/tests/ptr.rs b/core/tests/ptr.rs index 91f8c977d088a..7cefb615d0371 100644 --- a/core/tests/ptr.rs +++ b/core/tests/ptr.rs @@ -304,6 +304,7 @@ fn test_const_nonnull_new() { #[test] #[cfg(unix)] // printf may not be available on other platforms #[allow(deprecated)] // For SipHasher +#[allow(unpredictable_function_pointer_comparisons)] pub fn test_variadic_fnptr() { use core::ffi; use core::hash::{Hash, SipHasher}; @@ -859,7 +860,10 @@ fn swap_copy_untyped() { } #[test] -fn test_const_copy() { +fn test_const_copy_ptr() { + // `copy` and `copy_nonoverlapping` are thin layers on top of intrinsics. Ensure they correctly + // deal with pointers even when the pointers cross the boundary from one "element" being copied + // to another. const { let ptr1 = &1; let mut ptr2 = &666; @@ -897,6 +901,65 @@ fn test_const_copy() { }; } +#[test] +fn test_const_swap_ptr() { + // The `swap` functions are implemented in the library, they are not primitives. + // Only `swap_nonoverlapping` takes a count; pointers that cross multiple elements + // are *not* supported. + // We put the pointer at an odd offset in the type and copy them as an array of bytes, + // which should catch most of the ways that the library implementation can get it wrong. + + #[cfg(target_pointer_width = "32")] + type HalfPtr = i16; + #[cfg(target_pointer_width = "64")] + type HalfPtr = i32; + + #[repr(C, packed)] + #[allow(unused)] + struct S { + f1: HalfPtr, + // Crucially this field is at an offset that is not a multiple of the pointer size. + ptr: &'static i32, + // Make sure the entire type does not have a power-of-2 size: + // make it 3 pointers in size. This used to hit a bug in `swap_nonoverlapping`. + f2: [HalfPtr; 3], + } + + // Ensure the entire thing is usize-aligned, so in principle this + // looks like it could be eligible for a `usize` copying loop. + #[cfg_attr(target_pointer_width = "32", repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", repr(align(8)))] + struct A(S); + + const { + let mut s1 = A(S { ptr: &1, f1: 0, f2: [0; 3] }); + let mut s2 = A(S { ptr: &666, f1: 0, f2: [0; 3] }); + + // Swap ptr1 and ptr2, as an array. + type T = [u8; mem::size_of::()]; + unsafe { + ptr::swap(ptr::from_mut(&mut s1).cast::(), ptr::from_mut(&mut s2).cast::()); + } + + // Make sure they still work. + assert!(*s1.0.ptr == 666); + assert!(*s2.0.ptr == 1); + + // Swap them back, again as an array. + unsafe { + ptr::swap_nonoverlapping( + ptr::from_mut(&mut s1).cast::(), + ptr::from_mut(&mut s2).cast::(), + 1, + ); + } + + // Make sure they still work. + assert!(*s1.0.ptr == 1); + assert!(*s2.0.ptr == 666); + }; +} + #[test] fn test_null_array_as_slice() { let arr: *mut [u8; 4] = null_mut(); diff --git a/core/tests/slice.rs b/core/tests/slice.rs index 9ae2bcc852649..510dd4967c961 100644 --- a/core/tests/slice.rs +++ b/core/tests/slice.rs @@ -2,6 +2,7 @@ use core::cell::Cell; use core::cmp::Ordering; use core::mem::MaybeUninit; use core::num::NonZero; +use core::ops::{Range, RangeInclusive}; use core::slice; #[test] @@ -2553,6 +2554,14 @@ fn test_get_many_mut_normal_2() { *a += 10; *b += 100; assert_eq!(v, vec![101, 2, 3, 14, 5]); + + let [a, b] = v.get_many_mut([0..=1, 2..=2]).unwrap(); + assert_eq!(a, &mut [101, 2][..]); + assert_eq!(b, &mut [3][..]); + a[0] += 10; + a[1] += 20; + b[0] += 100; + assert_eq!(v, vec![111, 22, 103, 14, 5]); } #[test] @@ -2563,12 +2572,23 @@ fn test_get_many_mut_normal_3() { *b += 100; *c += 1000; assert_eq!(v, vec![11, 2, 1003, 4, 105]); + + let [a, b, c] = v.get_many_mut([0..1, 4..5, 1..4]).unwrap(); + assert_eq!(a, &mut [11][..]); + assert_eq!(b, &mut [105][..]); + assert_eq!(c, &mut [2, 1003, 4][..]); + a[0] += 10; + b[0] += 100; + c[0] += 1000; + assert_eq!(v, vec![21, 1002, 1003, 4, 205]); } #[test] fn test_get_many_mut_empty() { let mut v = vec![1, 2, 3, 4, 5]; - let [] = v.get_many_mut([]).unwrap(); + let [] = v.get_many_mut::([]).unwrap(); + let [] = v.get_many_mut::, 0>([]).unwrap(); + let [] = v.get_many_mut::, 0>([]).unwrap(); assert_eq!(v, vec![1, 2, 3, 4, 5]); } @@ -2606,6 +2626,54 @@ fn test_get_many_mut_duplicate() { assert!(v.get_many_mut([1, 3, 3, 4]).is_err()); } +#[test] +fn test_get_many_mut_range_oob() { + let mut v = vec![1, 2, 3, 4, 5]; + assert!(v.get_many_mut([0..6]).is_err()); + assert!(v.get_many_mut([5..6]).is_err()); + assert!(v.get_many_mut([6..6]).is_err()); + assert!(v.get_many_mut([0..=5]).is_err()); + assert!(v.get_many_mut([0..=6]).is_err()); + assert!(v.get_many_mut([5..=5]).is_err()); +} + +#[test] +fn test_get_many_mut_range_overlapping() { + let mut v = vec![1, 2, 3, 4, 5]; + assert!(v.get_many_mut([0..1, 0..2]).is_err()); + assert!(v.get_many_mut([0..1, 1..2, 0..1]).is_err()); + assert!(v.get_many_mut([0..3, 1..1]).is_err()); + assert!(v.get_many_mut([0..3, 1..2]).is_err()); + assert!(v.get_many_mut([0..=0, 2..=2, 0..=1]).is_err()); + assert!(v.get_many_mut([0..=4, 0..=0]).is_err()); + assert!(v.get_many_mut([4..=4, 0..=0, 3..=4]).is_err()); +} + +#[test] +fn test_get_many_mut_range_empty_at_edge() { + let mut v = vec![1, 2, 3, 4, 5]; + assert_eq!( + v.get_many_mut([0..0, 0..5, 5..5]), + Ok([&mut [][..], &mut [1, 2, 3, 4, 5], &mut []]), + ); + assert_eq!( + v.get_many_mut([0..0, 0..1, 1..1, 1..2, 2..2, 2..3, 3..3, 3..4, 4..4, 4..5, 5..5]), + Ok([ + &mut [][..], + &mut [1], + &mut [], + &mut [2], + &mut [], + &mut [3], + &mut [], + &mut [4], + &mut [], + &mut [5], + &mut [], + ]), + ); +} + #[test] fn test_slice_from_raw_parts_in_const() { static FANCY: i32 = 4; diff --git a/panic_unwind/Cargo.toml b/panic_unwind/Cargo.toml index 6d1f9764efbfd..c2abb79192e9f 100644 --- a/panic_unwind/Cargo.toml +++ b/panic_unwind/Cargo.toml @@ -23,7 +23,4 @@ libc = { version = "0.2", default-features = false } [lints.rust.unexpected_cfgs] level = "warn" -check-cfg = [ - # #[cfg(bootstrap)] rtems - 'cfg(target_os, values("rtems"))', -] +check-cfg = ['cfg(emscripten_wasm_eh)'] diff --git a/panic_unwind/src/gcc.rs b/panic_unwind/src/gcc.rs index 925af6c08322e..b2389078afd0f 100644 --- a/panic_unwind/src/gcc.rs +++ b/panic_unwind/src/gcc.rs @@ -5,7 +5,7 @@ //! documents linked from it. //! These are also good reads: //! * -//! * +//! * //! * //! //! ## A brief summary diff --git a/panic_unwind/src/lib.rs b/panic_unwind/src/lib.rs index 1981675f40922..dc78be76cb4d5 100644 --- a/panic_unwind/src/lib.rs +++ b/panic_unwind/src/lib.rs @@ -25,13 +25,14 @@ // `real_imp` is unused with Miri, so silence warnings. #![cfg_attr(miri, allow(dead_code))] #![allow(internal_features)] +#![cfg_attr(not(bootstrap), feature(cfg_emscripten_wasm_eh))] use alloc::boxed::Box; use core::any::Any; use core::panic::PanicPayload; cfg_if::cfg_if! { - if #[cfg(target_os = "emscripten")] { + if #[cfg(all(target_os = "emscripten", not(emscripten_wasm_eh)))] { #[path = "emcc.rs"] mod imp; } else if #[cfg(target_os = "hermit")] { @@ -46,7 +47,7 @@ cfg_if::cfg_if! { target_os = "psp", target_os = "xous", target_os = "solid_asp3", - all(target_family = "unix", not(any(target_os = "espidf", target_os = "rtems", target_os = "nuttx"))), + all(target_family = "unix", not(any(target_os = "espidf", target_os = "nuttx"))), all(target_vendor = "fortanix", target_env = "sgx"), target_family = "wasm", ))] { diff --git a/panic_unwind/src/seh.rs b/panic_unwind/src/seh.rs index 565a2b8c573b4..5afa0a1975612 100644 --- a/panic_unwind/src/seh.rs +++ b/panic_unwind/src/seh.rs @@ -288,8 +288,6 @@ cfg_if::cfg_if! { } } -// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint -#[allow(static_mut_refs)] pub unsafe fn panic(data: Box) -> u32 { use core::intrinsics::atomic_store_seqcst; diff --git a/portable-simd/crates/core_simd/src/vendor/arm.rs b/portable-simd/crates/core_simd/src/vendor/arm.rs index f8878d11f094d..3dc54481b6fd4 100644 --- a/portable-simd/crates/core_simd/src/vendor/arm.rs +++ b/portable-simd/crates/core_simd/src/vendor/arm.rs @@ -48,17 +48,6 @@ mod neon { from_transmute! { unsafe u64x2 => poly64x2_t } } -#[cfg(any( - all(target_feature = "v5te", not(target_feature = "mclass")), - all(target_feature = "mclass", target_feature = "dsp"), -))] -mod dsp { - use super::*; - - from_transmute! { unsafe Simd => uint16x2_t } - from_transmute! { unsafe Simd => int16x2_t } -} - #[cfg(any( all(target_feature = "v6", not(target_feature = "mclass")), all(target_feature = "mclass", target_feature = "dsp"), @@ -68,6 +57,8 @@ mod simd32 { from_transmute! { unsafe Simd => uint8x4_t } from_transmute! { unsafe Simd => int8x4_t } + from_transmute! { unsafe Simd => uint16x2_t } + from_transmute! { unsafe Simd => int16x2_t } } #[cfg(all( diff --git a/proc_macro/src/bridge/arena.rs b/proc_macro/src/bridge/arena.rs index 1d5986093c8a4..29636e793f614 100644 --- a/proc_macro/src/bridge/arena.rs +++ b/proc_macro/src/bridge/arena.rs @@ -102,7 +102,7 @@ impl Arena { #[allow(clippy::mut_from_ref)] // arena allocator pub(crate) fn alloc_str<'a>(&'a self, string: &str) -> &'a mut str { let alloc = self.alloc_raw(string.len()); - let bytes = MaybeUninit::copy_from_slice(alloc, string.as_bytes()); + let bytes = alloc.write_copy_of_slice(string.as_bytes()); // SAFETY: we convert from `&str` to `&[u8]`, clone it into the arena, // and immediately convert the clone back to `&str`. diff --git a/proc_macro/src/bridge/fxhash.rs b/proc_macro/src/bridge/fxhash.rs index 74a41451825ff..3345e099a3724 100644 --- a/proc_macro/src/bridge/fxhash.rs +++ b/proc_macro/src/bridge/fxhash.rs @@ -22,6 +22,7 @@ pub type FxHashMap = HashMap>; /// out-performs an FNV-based hash within rustc itself -- the collision rate is /// similar or slightly worse than FNV, but the speed of the hash function /// itself is much higher because it works on up to 8 bytes at a time. +#[derive(Default)] pub struct FxHasher { hash: usize, } @@ -31,13 +32,6 @@ const K: usize = 0x9e3779b9; #[cfg(target_pointer_width = "64")] const K: usize = 0x517cc1b727220a95; -impl Default for FxHasher { - #[inline] - fn default() -> FxHasher { - FxHasher { hash: 0 } - } -} - impl FxHasher { #[inline] fn add_to_hash(&mut self, i: usize) { diff --git a/proc_macro/src/bridge/symbol.rs b/proc_macro/src/bridge/symbol.rs index edad6e7ac393f..6a1cecd69fb5f 100644 --- a/proc_macro/src/bridge/symbol.rs +++ b/proc_macro/src/bridge/symbol.rs @@ -91,12 +91,6 @@ impl fmt::Debug for Symbol { } } -impl ToString for Symbol { - fn to_string(&self) -> String { - self.with(|s| s.to_owned()) - } -} - impl fmt::Display for Symbol { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.with(|s| fmt::Display::fmt(s, f)) diff --git a/proc_macro/src/lib.rs b/proc_macro/src/lib.rs index 15770248b3106..b19c9cee75a0b 100644 --- a/proc_macro/src/lib.rs +++ b/proc_macro/src/lib.rs @@ -19,10 +19,6 @@ )] #![doc(rust_logo)] #![feature(rustdoc_internals)] -// This library is copied into rust-analyzer to allow loading rustc compiled proc macros. -// Please avoid unstable features where possible to minimize the amount of changes necessary -// to make it compile with rust-analyzer on stable. -#![feature(rustc_allow_const_fn_unstable)] #![feature(staged_api)] #![feature(allow_internal_unstable)] #![feature(decl_macro)] @@ -31,7 +27,6 @@ #![feature(panic_can_unwind)] #![feature(restricted_std)] #![feature(rustc_attrs)] -#![feature(min_specialization)] #![feature(extend_one)] #![recursion_limit = "256"] #![allow(internal_features)] @@ -186,16 +181,6 @@ impl FromStr for TokenStream { } } -// N.B., the bridge only provides `to_string`, implement `fmt::Display` -// based on it (the reverse of the usual relationship between the two). -#[doc(hidden)] -#[stable(feature = "proc_macro_lib", since = "1.15.0")] -impl ToString for TokenStream { - fn to_string(&self) -> String { - self.0.as_ref().map(|t| t.to_string()).unwrap_or_default() - } -} - /// Prints the token stream as a string that is supposed to be losslessly convertible back /// into the same token stream (modulo spans), except for possibly `TokenTree::Group`s /// with `Delimiter::None` delimiters and negative numeric literals. @@ -211,7 +196,10 @@ impl ToString for TokenStream { impl fmt::Display for TokenStream { #[allow(clippy::recursive_format_impl)] // clippy doesn't see the specialization fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(&self.to_string()) + match &self.0 { + Some(ts) => write!(f, "{}", ts.to_string()), + None => Ok(()), + } } } @@ -431,7 +419,7 @@ pub mod token_stream { /// Unquoting is done with `$`, and works by taking the single next ident as the unquoted term. /// To quote `$` itself, use `$$`. #[unstable(feature = "proc_macro_quote", issue = "54722")] -#[allow_internal_unstable(proc_macro_def_site, proc_macro_internals)] +#[allow_internal_unstable(proc_macro_def_site, proc_macro_internals, proc_macro_totokens)] #[rustc_builtin_macro] pub macro quote($($t:tt)*) { /* compiler built-in */ @@ -757,21 +745,6 @@ impl From for TokenTree { } } -// N.B., the bridge only provides `to_string`, implement `fmt::Display` -// based on it (the reverse of the usual relationship between the two). -#[doc(hidden)] -#[stable(feature = "proc_macro_lib", since = "1.15.0")] -impl ToString for TokenTree { - fn to_string(&self) -> String { - match *self { - TokenTree::Group(ref t) => t.to_string(), - TokenTree::Ident(ref t) => t.to_string(), - TokenTree::Punct(ref t) => t.to_string(), - TokenTree::Literal(ref t) => t.to_string(), - } - } -} - /// Prints the token tree as a string that is supposed to be losslessly convertible back /// into the same token tree (modulo spans), except for possibly `TokenTree::Group`s /// with `Delimiter::None` delimiters and negative numeric literals. @@ -787,7 +760,12 @@ impl ToString for TokenTree { impl fmt::Display for TokenTree { #[allow(clippy::recursive_format_impl)] // clippy doesn't see the specialization fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(&self.to_string()) + match self { + TokenTree::Group(t) => write!(f, "{t}"), + TokenTree::Ident(t) => write!(f, "{t}"), + TokenTree::Punct(t) => write!(f, "{t}"), + TokenTree::Literal(t) => write!(f, "{t}"), + } } } @@ -913,16 +891,6 @@ impl Group { } } -// N.B., the bridge only provides `to_string`, implement `fmt::Display` -// based on it (the reverse of the usual relationship between the two). -#[doc(hidden)] -#[stable(feature = "proc_macro_lib", since = "1.15.0")] -impl ToString for Group { - fn to_string(&self) -> String { - TokenStream::from(TokenTree::from(self.clone())).to_string() - } -} - /// Prints the group as a string that should be losslessly convertible back /// into the same group (modulo spans), except for possibly `TokenTree::Group`s /// with `Delimiter::None` delimiters. @@ -930,7 +898,7 @@ impl ToString for Group { impl fmt::Display for Group { #[allow(clippy::recursive_format_impl)] // clippy doesn't see the specialization fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(&self.to_string()) + write!(f, "{}", TokenStream::from(TokenTree::from(self.clone()))) } } @@ -1036,14 +1004,6 @@ impl Punct { } } -#[doc(hidden)] -#[stable(feature = "proc_macro_lib2", since = "1.29.0")] -impl ToString for Punct { - fn to_string(&self) -> String { - self.as_char().to_string() - } -} - /// Prints the punctuation character as a string that should be losslessly convertible /// back into the same character. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] @@ -1139,14 +1099,6 @@ impl Ident { } } -#[doc(hidden)] -#[stable(feature = "proc_macro_lib2", since = "1.29.0")] -impl ToString for Ident { - fn to_string(&self) -> String { - self.0.sym.with(|sym| if self.0.is_raw { ["r#", sym].concat() } else { sym.to_owned() }) - } -} - /// Prints the identifier as a string that should be losslessly convertible back /// into the same identifier. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] @@ -1521,14 +1473,6 @@ impl FromStr for Literal { } } -#[doc(hidden)] -#[stable(feature = "proc_macro_lib2", since = "1.29.0")] -impl ToString for Literal { - fn to_string(&self) -> String { - self.with_stringify_parts(|parts| parts.concat()) - } -} - /// Prints the literal as a string that should be losslessly convertible /// back into the same literal (except for possible rounding for floating point literals). #[stable(feature = "proc_macro_lib2", since = "1.29.0")] diff --git a/proc_macro/src/quote.rs b/proc_macro/src/quote.rs index 04fa696d5e6be..bcb15912bb65e 100644 --- a/proc_macro/src/quote.rs +++ b/proc_macro/src/quote.rs @@ -4,12 +4,14 @@ //! This quasiquoter uses macros 2.0 hygiene to reliably access //! items from `proc_macro`, to build a `proc_macro::TokenStream`. -use crate::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; +use crate::{ + Delimiter, Group, Ident, Literal, Punct, Spacing, Span, ToTokens, TokenStream, TokenTree, +}; -macro_rules! quote_tt { - (($($t:tt)*)) => { Group::new(Delimiter::Parenthesis, quote!($($t)*)) }; - ([$($t:tt)*]) => { Group::new(Delimiter::Bracket, quote!($($t)*)) }; - ({$($t:tt)*}) => { Group::new(Delimiter::Brace, quote!($($t)*)) }; +macro_rules! minimal_quote_tt { + (($($t:tt)*)) => { Group::new(Delimiter::Parenthesis, minimal_quote!($($t)*)) }; + ([$($t:tt)*]) => { Group::new(Delimiter::Bracket, minimal_quote!($($t)*)) }; + ({$($t:tt)*}) => { Group::new(Delimiter::Brace, minimal_quote!($($t)*)) }; (,) => { Punct::new(',', Spacing::Alone) }; (.) => { Punct::new('.', Spacing::Alone) }; (;) => { Punct::new(';', Spacing::Alone) }; @@ -21,21 +23,20 @@ macro_rules! quote_tt { ($i:ident) => { Ident::new(stringify!($i), Span::def_site()) }; } -macro_rules! quote_ts { +macro_rules! minimal_quote_ts { ((@ $($t:tt)*)) => { $($t)* }; (::) => { - [ - TokenTree::from(Punct::new(':', Spacing::Joint)), - TokenTree::from(Punct::new(':', Spacing::Alone)), - ].iter() - .cloned() - .map(|mut x| { - x.set_span(Span::def_site()); - x - }) - .collect::() + { + let mut c = ( + TokenTree::from(Punct::new(':', Spacing::Joint)), + TokenTree::from(Punct::new(':', Spacing::Alone)) + ); + c.0.set_span(Span::def_site()); + c.1.set_span(Span::def_site()); + [c.0, c.1].into_iter().collect::() + } }; - ($t:tt) => { TokenTree::from(quote_tt!($t)) }; + ($t:tt) => { TokenTree::from(minimal_quote_tt!($t)) }; } /// Simpler version of the real `quote!` macro, implemented solely @@ -46,12 +47,14 @@ macro_rules! quote_ts { /// /// Note: supported tokens are a subset of the real `quote!`, but /// unquoting is different: instead of `$x`, this uses `(@ expr)`. -macro_rules! quote { - () => { TokenStream::new() }; +macro_rules! minimal_quote { ($($t:tt)*) => { - [ - $(TokenStream::from(quote_ts!($t)),)* - ].iter().cloned().collect::() + { + #[allow(unused_mut)] // In case the expansion is empty + let mut ts = TokenStream::new(); + $(ToTokens::to_tokens(&minimal_quote_ts!($t), &mut ts);)* + ts + } }; } @@ -62,52 +65,66 @@ macro_rules! quote { #[unstable(feature = "proc_macro_quote", issue = "54722")] pub fn quote(stream: TokenStream) -> TokenStream { if stream.is_empty() { - return quote!(crate::TokenStream::new()); + return minimal_quote!(crate::TokenStream::new()); } - let proc_macro_crate = quote!(crate); + let proc_macro_crate = minimal_quote!(crate); let mut after_dollar = false; - let tokens = stream - .into_iter() - .filter_map(|tree| { - if after_dollar { - after_dollar = false; - match tree { - TokenTree::Ident(_) => { - return Some(quote!(Into::::into( - Clone::clone(&(@ tree))),)); - } - TokenTree::Punct(ref tt) if tt.as_char() == '$' => {} - _ => panic!("`$` must be followed by an ident or `$` in `quote!`"), - } - } else if let TokenTree::Punct(ref tt) = tree { - if tt.as_char() == '$' { - after_dollar = true; - return None; + + let mut tokens = crate::TokenStream::new(); + for tree in stream { + if after_dollar { + after_dollar = false; + match tree { + TokenTree::Ident(_) => { + minimal_quote!(crate::ToTokens::to_tokens(&(@ tree), &mut ts);) + .to_tokens(&mut tokens); + continue; } + TokenTree::Punct(ref tt) if tt.as_char() == '$' => {} + _ => panic!("`$` must be followed by an ident or `$` in `quote!`"), } + } else if let TokenTree::Punct(ref tt) = tree { + if tt.as_char() == '$' { + after_dollar = true; + continue; + } + } - Some(quote!(crate::TokenStream::from((@ match tree { - TokenTree::Punct(tt) => quote!(crate::TokenTree::Punct(crate::Punct::new( + match tree { + TokenTree::Punct(tt) => { + minimal_quote!(crate::ToTokens::to_tokens(&crate::TokenTree::Punct(crate::Punct::new( (@ TokenTree::from(Literal::character(tt.as_char()))), (@ match tt.spacing() { - Spacing::Alone => quote!(crate::Spacing::Alone), - Spacing::Joint => quote!(crate::Spacing::Joint), + Spacing::Alone => minimal_quote!(crate::Spacing::Alone), + Spacing::Joint => minimal_quote!(crate::Spacing::Joint), }), - ))), - TokenTree::Group(tt) => quote!(crate::TokenTree::Group(crate::Group::new( + )), &mut ts);) + } + TokenTree::Group(tt) => { + minimal_quote!(crate::ToTokens::to_tokens(&crate::TokenTree::Group(crate::Group::new( (@ match tt.delimiter() { - Delimiter::Parenthesis => quote!(crate::Delimiter::Parenthesis), - Delimiter::Brace => quote!(crate::Delimiter::Brace), - Delimiter::Bracket => quote!(crate::Delimiter::Bracket), - Delimiter::None => quote!(crate::Delimiter::None), + Delimiter::Parenthesis => minimal_quote!(crate::Delimiter::Parenthesis), + Delimiter::Brace => minimal_quote!(crate::Delimiter::Brace), + Delimiter::Bracket => minimal_quote!(crate::Delimiter::Bracket), + Delimiter::None => minimal_quote!(crate::Delimiter::None), }), (@ quote(tt.stream())), - ))), - TokenTree::Ident(tt) => quote!(crate::TokenTree::Ident(crate::Ident::new( - (@ TokenTree::from(Literal::string(&tt.to_string()))), + )), &mut ts);) + } + TokenTree::Ident(tt) => { + let literal = tt.to_string(); + let (literal, ctor) = if let Some(stripped) = literal.strip_prefix("r#") { + (stripped, minimal_quote!(crate::Ident::new_raw)) + } else { + (literal.as_str(), minimal_quote!(crate::Ident::new)) + }; + minimal_quote!(crate::ToTokens::to_tokens(&crate::TokenTree::Ident((@ ctor)( + (@ TokenTree::from(Literal::string(literal))), (@ quote_span(proc_macro_crate.clone(), tt.span())), - ))), - TokenTree::Literal(tt) => quote!(crate::TokenTree::Literal({ + )), &mut ts);) + } + TokenTree::Literal(tt) => { + minimal_quote!(crate::ToTokens::to_tokens(&crate::TokenTree::Literal({ let mut iter = (@ TokenTree::from(Literal::string(&tt.to_string()))) .parse::() .unwrap() @@ -120,16 +137,22 @@ pub fn quote(stream: TokenStream) -> TokenStream { } else { unreachable!() } - })) - })),)) - }) - .collect::(); - + }), &mut ts);) + } + } + .to_tokens(&mut tokens); + } if after_dollar { panic!("unexpected trailing `$` in `quote!`"); } - quote!([(@ tokens)].iter().cloned().collect::()) + minimal_quote! { + { + let mut ts = crate::TokenStream::new(); + (@ tokens) + ts + } + } } /// Quote a `Span` into a `TokenStream`. @@ -137,5 +160,5 @@ pub fn quote(stream: TokenStream) -> TokenStream { #[unstable(feature = "proc_macro_quote", issue = "54722")] pub fn quote_span(proc_macro_crate: TokenStream, span: Span) -> TokenStream { let id = span.save_span(); - quote!((@ proc_macro_crate ) ::Span::recover_proc_macro_span((@ TokenTree::from(Literal::usize_unsuffixed(id))))) + minimal_quote!((@ proc_macro_crate ) ::Span::recover_proc_macro_span((@ TokenTree::from(Literal::usize_unsuffixed(id))))) } diff --git a/profiler_builtins/Cargo.toml b/profiler_builtins/Cargo.toml index 9aadefce3b39e..230e8051602e4 100644 --- a/profiler_builtins/Cargo.toml +++ b/profiler_builtins/Cargo.toml @@ -9,8 +9,7 @@ bench = false doc = false [dependencies] -core = { path = "../core" } -compiler_builtins = { version = "0.1.0", features = ['rustc-dep-of-std'] } [build-dependencies] -cc = "1.2" +# Pinned so `cargo update` bumps don't cause breakage +cc = "=1.2.0" diff --git a/profiler_builtins/src/lib.rs b/profiler_builtins/src/lib.rs index ac685b18c2911..a258f7d31a191 100644 --- a/profiler_builtins/src/lib.rs +++ b/profiler_builtins/src/lib.rs @@ -1,11 +1,15 @@ -#![no_std] +// tidy-alphabetical-start +#![allow(internal_features)] +#![feature(no_core)] #![feature(profiler_runtime)] +#![feature(staged_api)] +// tidy-alphabetical-end + +// Other attributes: +#![no_core] #![profiler_runtime] #![unstable( feature = "profiler_runtime_lib", reason = "internal implementation detail of rustc right now", issue = "none" )] -#![allow(unused_features)] -#![allow(internal_features)] -#![feature(staged_api)] diff --git a/std/Cargo.toml b/std/Cargo.toml index c1ab70b714a4c..da58d7c13bd12 100644 --- a/std/Cargo.toml +++ b/std/Cargo.toml @@ -17,7 +17,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.138" } +compiler_builtins = { version = "=0.1.143" } unwind = { path = "../unwind" } hashbrown = { version = "0.15", default-features = false, features = [ 'rustc-dep-of-std', @@ -30,11 +30,11 @@ std_detect = { path = "../stdarch/crates/std_detect", default-features = false, rustc-demangle = { version = "0.1.24", features = ['rustc-dep-of-std'] } [target.'cfg(not(all(windows, target_env = "msvc", not(target_vendor = "uwp"))))'.dependencies] -miniz_oxide = { version = "0.7.0", optional = true, default-features = false } -addr2line = { version = "0.22.0", optional = true, default-features = false } +miniz_oxide = { version = "0.8.0", optional = true, default-features = false } +addr2line = { version = "0.24.0", optional = true, default-features = false } [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] -libc = { version = "0.2.162", default-features = false, features = [ +libc = { version = "0.2.169", default-features = false, features = [ 'rustc-dep-of-std', ], public = true } @@ -144,6 +144,4 @@ check-cfg = [ # and to the `backtrace` crate which messes-up with Cargo list # of declared features, we therefor expect any feature cfg 'cfg(feature, values(any()))', - # #[cfg(bootstrap)] rtems - 'cfg(target_os, values("rtems"))', ] diff --git a/std/src/collections/hash/map.rs b/std/src/collections/hash/map.rs index 24bbc2f32cf6d..d2342d8fd5176 100644 --- a/std/src/collections/hash/map.rs +++ b/std/src/collections/hash/map.rs @@ -204,6 +204,25 @@ use crate::ops::Index; /// println!("{viking:?} has {health} hp"); /// } /// ``` +/// +/// # Usage in `const` and `static` +/// +/// As explained above, `HashMap` is randomly seeded: each `HashMap` instance uses a different seed, +/// which means that `HashMap::new` cannot be used in const context. To construct a `HashMap` in the +/// initializer of a `const` or `static` item, you will have to use a different hasher that does not +/// involve a random seed, as demonstrated in the following example. **A `HashMap` constructed this +/// way is not resistant against HashDoS!** +/// +/// ```rust +/// use std::collections::HashMap; +/// use std::hash::{BuildHasherDefault, DefaultHasher}; +/// use std::sync::Mutex; +/// +/// const EMPTY_MAP: HashMap, BuildHasherDefault> = +/// HashMap::with_hasher(BuildHasherDefault::new()); +/// static MAP: Mutex, BuildHasherDefault>> = +/// Mutex::new(HashMap::with_hasher(BuildHasherDefault::new())); +/// ``` #[cfg_attr(not(test), rustc_diagnostic_item = "HashMap")] #[stable(feature = "rust1", since = "1.0.0")] @@ -235,7 +254,7 @@ impl HashMap { /// /// The hash map will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the hash map will not allocate. + /// `capacity`. If `capacity` is zero, the hash map will not allocate. /// /// # Examples /// @@ -277,7 +296,7 @@ impl HashMap { /// ``` #[inline] #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_collections_with_hasher", issue = "102575")] + #[rustc_const_stable(feature = "const_collections_with_hasher", since = "1.85.0")] pub const fn with_hasher(hash_builder: S) -> HashMap { HashMap { base: base::HashMap::with_hasher(hash_builder) } } @@ -287,7 +306,7 @@ impl HashMap { /// /// The hash map will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the hash map will not allocate. + /// `capacity`. If `capacity` is zero, the hash map will not allocate. /// /// Warning: `hasher` is normally randomly generated, and /// is designed to allow HashMaps to be resistant to attacks that @@ -1424,6 +1443,11 @@ impl From<[(K, V); N]> for HashMap where K: Eq + Hash, { + /// Converts a `[(K, V); N]` into a `HashMap`. + /// + /// If any entries in the array have equal keys, + /// all but one of the corresponding values will be dropped. + /// /// # Examples /// /// ``` @@ -3197,6 +3221,10 @@ where K: Eq + Hash, S: BuildHasher + Default, { + /// Constructs a `HashMap` from an iterator of key-value pairs. + /// + /// If the iterator produces any pairs with equal keys, + /// all but one of the corresponding values will be dropped. fn from_iter>(iter: T) -> HashMap { let mut map = HashMap::with_hasher(Default::default()); map.extend(iter); diff --git a/std/src/collections/hash/set.rs b/std/src/collections/hash/set.rs index f86bcdb4796ec..bbb6ca2352136 100644 --- a/std/src/collections/hash/set.rs +++ b/std/src/collections/hash/set.rs @@ -101,6 +101,25 @@ use crate::ops::{BitAnd, BitOr, BitXor, Sub}; /// [`HashMap`]: crate::collections::HashMap /// [`RefCell`]: crate::cell::RefCell /// [`Cell`]: crate::cell::Cell +/// +/// # Usage in `const` and `static` +/// +/// Like `HashMap`, `HashSet` is randomly seeded: each `HashSet` instance uses a different seed, +/// which means that `HashSet::new` cannot be used in const context. To construct a `HashSet` in the +/// initializer of a `const` or `static` item, you will have to use a different hasher that does not +/// involve a random seed, as demonstrated in the following example. **A `HashSet` constructed this +/// way is not resistant against HashDoS!** +/// +/// ```rust +/// use std::collections::HashSet; +/// use std::hash::{BuildHasherDefault, DefaultHasher}; +/// use std::sync::Mutex; +/// +/// const EMPTY_SET: HashSet> = +/// HashSet::with_hasher(BuildHasherDefault::new()); +/// static SET: Mutex>> = +/// Mutex::new(HashSet::with_hasher(BuildHasherDefault::new())); +/// ``` #[cfg_attr(not(test), rustc_diagnostic_item = "HashSet")] #[stable(feature = "rust1", since = "1.0.0")] pub struct HashSet { @@ -130,7 +149,7 @@ impl HashSet { /// /// The hash set will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the hash set will not allocate. + /// `capacity`. If `capacity` is zero, the hash set will not allocate. /// /// # Examples /// @@ -369,7 +388,7 @@ impl HashSet { /// ``` #[inline] #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_collections_with_hasher", issue = "102575")] + #[rustc_const_stable(feature = "const_collections_with_hasher", since = "1.85.0")] pub const fn with_hasher(hasher: S) -> HashSet { HashSet { base: base::HashSet::with_hasher(hasher) } } @@ -379,7 +398,7 @@ impl HashSet { /// /// The hash set will be able to hold at least `capacity` elements without /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is 0, the hash set will not allocate. + /// `capacity`. If `capacity` is zero, the hash set will not allocate. /// /// Warning: `hasher` is normally randomly generated, and /// is designed to allow `HashSet`s to be resistant to attacks that @@ -1069,6 +1088,11 @@ impl From<[T; N]> for HashSet where T: Eq + Hash, { + /// Converts a `[T; N]` into a `HashSet`. + /// + /// If the array contains any equal values, + /// all but one will be dropped. + /// /// # Examples /// /// ``` diff --git a/std/src/env.rs b/std/src/env.rs index 27f4daba44bf6..11a29cdae62e2 100644 --- a/std/src/env.rs +++ b/std/src/env.rs @@ -597,6 +597,13 @@ impl Error for JoinPathsError { /// Returns the path of the current user's home directory if known. /// +/// This may return `None` if getting the directory fails or if the platform does not have user home directories. +/// +/// For storing user data and configuration it is often preferable to use more specific directories. +/// For example, [XDG Base Directories] on Unix or the `LOCALAPPDATA` and `APPDATA` environment variables on Windows. +/// +/// [XDG Base Directories]: https://specifications.freedesktop.org/basedir-spec/latest/ +/// /// # Unix /// /// - Returns the value of the 'HOME' environment variable if it is set @@ -608,20 +615,16 @@ impl Error for JoinPathsError { /// /// # Windows /// -/// - Returns the value of the 'HOME' environment variable if it is set -/// (including to an empty string). -/// - Otherwise, returns the value of the 'USERPROFILE' environment variable if it is set -/// (including to an empty string). -/// - If both do not exist, [`GetUserProfileDirectory`][msdn] is used to return the path. +/// - Returns the value of the 'USERPROFILE' environment variable if it is set, and is not an empty string. +/// - Otherwise, [`GetUserProfileDirectory`][msdn] is used to return the path. This may change in the future. /// /// [msdn]: https://docs.microsoft.com/en-us/windows/win32/api/userenv/nf-userenv-getuserprofiledirectorya /// -/// # Deprecation +/// In UWP (Universal Windows Platform) targets this function is unimplemented and always returns `None`. /// -/// This function is deprecated because the behavior on Windows is not correct. -/// The 'HOME' environment variable is not standard on Windows, and may not produce -/// desired results; for instance, under Cygwin or Mingw it will return `/home/you` -/// when it should return `C:\Users\you`. +/// Before Rust 1.85.0, this function used to return the value of the 'HOME' environment variable +/// on Windows, which in Cygwin or Mingw environments could return non-standard paths like `/home/you` +/// instead of `C:\Users\you`. /// /// # Examples /// diff --git a/std/src/f128.rs b/std/src/f128.rs index e93e915159e40..4f37e18a8cd76 100644 --- a/std/src/f128.rs +++ b/std/src/f128.rs @@ -227,6 +227,7 @@ impl f128 { /// ``` #[inline] #[rustc_allow_incoherent_impl] + #[doc(alias = "fmaf128", alias = "fusedMultiplyAdd")] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn mul_add(self, a: f128, b: f128) -> f128 { @@ -384,6 +385,7 @@ impl f128 { /// # } /// ``` #[inline] + #[doc(alias = "squareRoot")] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] diff --git a/std/src/f16.rs b/std/src/f16.rs index 5b7fcaa28e064..42cd6e3fe2a5f 100644 --- a/std/src/f16.rs +++ b/std/src/f16.rs @@ -228,6 +228,7 @@ impl f16 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[doc(alias = "fmaf16", alias = "fusedMultiplyAdd")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn mul_add(self, a: f16, b: f16) -> f16 { unsafe { intrinsics::fmaf16(self, a, b) } @@ -384,6 +385,7 @@ impl f16 { /// # } /// ``` #[inline] + #[doc(alias = "squareRoot")] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] diff --git a/std/src/f32.rs b/std/src/f32.rs index 7cb285bbff5f7..438d77b1626be 100644 --- a/std/src/f32.rs +++ b/std/src/f32.rs @@ -210,6 +210,7 @@ impl f32 { /// assert_eq!(one_plus_eps * one_minus_eps + minus_one, 0.0); /// ``` #[rustc_allow_incoherent_impl] + #[doc(alias = "fmaf", alias = "fusedMultiplyAdd")] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -360,6 +361,7 @@ impl f32 { /// assert!(negative.sqrt().is_nan()); /// assert!(negative_zero.sqrt() == negative_zero); /// ``` + #[doc(alias = "squareRoot")] #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] diff --git a/std/src/f64.rs b/std/src/f64.rs index 47163c272de32..9bb4bfbab2a0f 100644 --- a/std/src/f64.rs +++ b/std/src/f64.rs @@ -210,6 +210,7 @@ impl f64 { /// assert_eq!(one_plus_eps * one_minus_eps + minus_one, 0.0); /// ``` #[rustc_allow_incoherent_impl] + #[doc(alias = "fma", alias = "fusedMultiplyAdd")] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -360,6 +361,7 @@ impl f64 { /// assert!(negative.sqrt().is_nan()); /// assert!(negative_zero.sqrt() == negative_zero); /// ``` + #[doc(alias = "squareRoot")] #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] diff --git a/std/src/ffi/mod.rs b/std/src/ffi/mod.rs index 469136be8838a..7d7cce09a3f09 100644 --- a/std/src/ffi/mod.rs +++ b/std/src/ffi/mod.rs @@ -179,19 +179,19 @@ pub use core::ffi::{ c_ulong, c_ulonglong, c_ushort, }; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")] pub use self::c_str::FromBytesUntilNulError; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "cstr_from_bytes", since = "1.10.0")] pub use self::c_str::FromBytesWithNulError; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")] pub use self::c_str::FromVecWithNulError; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "cstring_into", since = "1.7.0")] pub use self::c_str::IntoStringError; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "rust1", since = "1.0.0")] pub use self::c_str::NulError; #[doc(inline)] diff --git a/std/src/ffi/os_str.rs b/std/src/ffi/os_str.rs index 328185d1f2b0c..7fb57d410431e 100644 --- a/std/src/ffi/os_str.rs +++ b/std/src/ffi/os_str.rs @@ -550,7 +550,7 @@ impl OsString { OsStr::from_inner_mut(self.inner.leak()) } - /// Truncate the the `OsString` to the specified length. + /// Truncate the `OsString` to the specified length. /// /// # Panics /// Panics if `len` does not lie on a valid `OsStr` boundary @@ -1229,7 +1229,7 @@ impl From<&OsStr> for Box { } } -#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "box_from_mut_slice", since = "1.84.0")] impl From<&mut OsStr> for Box { /// Copies the string into a newly allocated [Box]<[OsStr]>. #[inline] @@ -1309,7 +1309,7 @@ impl From<&OsStr> for Arc { } } -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut OsStr> for Arc { /// Copies the string into a newly allocated [Arc]<[OsStr]>. #[inline] @@ -1339,7 +1339,7 @@ impl From<&OsStr> for Rc { } } -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut OsStr> for Rc { /// Copies the string into a newly allocated [Rc]<[OsStr]>. #[inline] diff --git a/std/src/ffi/os_str/tests.rs b/std/src/ffi/os_str/tests.rs index cbec44c862646..2572b71fd9ac6 100644 --- a/std/src/ffi/os_str/tests.rs +++ b/std/src/ffi/os_str/tests.rs @@ -295,7 +295,7 @@ fn clone_to_uninit() { let mut storage = vec![MaybeUninit::::uninit(); size_of_val::(a)]; unsafe { a.clone_to_uninit(ptr::from_mut::<[_]>(storage.as_mut_slice()).cast()) }; - assert_eq!(a.as_encoded_bytes(), unsafe { MaybeUninit::slice_assume_init_ref(&storage) }); + assert_eq!(a.as_encoded_bytes(), unsafe { storage.assume_init_ref() }); let mut b: Box = OsStr::new("world.exe").into(); assert_eq!(size_of_val::(a), size_of_val::(&b)); diff --git a/std/src/fs.rs b/std/src/fs.rs index d846a4e5f0916..9b752ed14437c 100644 --- a/std/src/fs.rs +++ b/std/src/fs.rs @@ -1869,8 +1869,10 @@ impl Permissions { /// /// # Note /// - /// This function does not take Access Control Lists (ACLs) or Unix group - /// membership into account. + /// This function does not take Access Control Lists (ACLs), Unix group + /// membership and other nuances into account. + /// Therefore the return value of this function cannot be relied upon + /// to predict whether attempts to read or write the file will actually succeed. /// /// # Windows /// @@ -1885,10 +1887,13 @@ impl Permissions { /// # Unix (including macOS) /// /// On Unix-based platforms this checks if *any* of the owner, group or others - /// write permission bits are set. It does not check if the current - /// user is in the file's assigned group. It also does not check ACLs. - /// Therefore the return value of this function cannot be relied upon - /// to predict whether attempts to read or write the file will actually succeed. + /// write permission bits are set. It does not consider anything else, including: + /// + /// * Whether the current user is in the file's assigned group. + /// * Permissions granted by ACL. + /// * That `root` user can write to files that do not have any write bits set. + /// * Writable files on a filesystem that is mounted read-only. + /// /// The [`PermissionsExt`] trait gives direct access to the permission bits but /// also does not read ACLs. /// @@ -2397,12 +2402,14 @@ pub fn symlink_metadata>(path: P) -> io::Result { /// # Platform-specific behavior /// /// This function currently corresponds to the `rename` function on Unix -/// and the `MoveFileEx` function with the `MOVEFILE_REPLACE_EXISTING` flag on Windows. +/// and the `SetFileInformationByHandle` function on Windows. /// /// Because of this, the behavior when both `from` and `to` exist differs. On /// Unix, if `from` is a directory, `to` must also be an (empty) directory. If -/// `from` is not a directory, `to` must also be not a directory. In contrast, -/// on Windows, `from` can be anything, but `to` must *not* be a directory. +/// `from` is not a directory, `to` must also be not a directory. The behavior +/// on Windows is the same on Windows 10 1607 and higher if `FileRenameInfoEx` +/// is supported by the filesystem; otherwise, `from` can be anything, but +/// `to` must *not* be a directory. /// /// Note that, this [may change in the future][changes]. /// @@ -3020,7 +3027,7 @@ impl DirBuilder { match path.parent() { Some(p) => self.create_dir_all(p)?, None => { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Uncategorized, "failed to create whole tree", )); diff --git a/std/src/fs/tests.rs b/std/src/fs/tests.rs index 018e19586418e..28f16da1ed8d2 100644 --- a/std/src/fs/tests.rs +++ b/std/src/fs/tests.rs @@ -1912,3 +1912,73 @@ fn test_hidden_file_truncation() { let metadata = file.metadata().unwrap(); assert_eq!(metadata.len(), 0); } + +#[cfg(windows)] +#[test] +fn test_rename_file_over_open_file() { + // Make sure that std::fs::rename works if the target file is already opened with FILE_SHARE_DELETE. See #123985. + let tmpdir = tmpdir(); + + // Create source with test data to read. + let source_path = tmpdir.join("source_file.txt"); + fs::write(&source_path, b"source hello world").unwrap(); + + // Create target file with test data to read; + let target_path = tmpdir.join("target_file.txt"); + fs::write(&target_path, b"target hello world").unwrap(); + + // Open target file + let target_file = fs::File::open(&target_path).unwrap(); + + // Rename source + fs::rename(source_path, &target_path).unwrap(); + + core::mem::drop(target_file); + assert_eq!(fs::read(target_path).unwrap(), b"source hello world"); +} + +#[test] +#[cfg(windows)] +fn test_rename_directory_to_non_empty_directory() { + // Renaming a directory over a non-empty existing directory should fail on Windows. + let tmpdir: TempDir = tmpdir(); + + let source_path = tmpdir.join("source_directory"); + let target_path = tmpdir.join("target_directory"); + + fs::create_dir(&source_path).unwrap(); + fs::create_dir(&target_path).unwrap(); + + fs::write(target_path.join("target_file.txt"), b"target hello world").unwrap(); + + error!(fs::rename(source_path, target_path), 145); // ERROR_DIR_NOT_EMPTY +} + +#[test] +fn test_rename_symlink() { + let tmpdir = tmpdir(); + let original = tmpdir.join("original"); + let dest = tmpdir.join("dest"); + let not_exist = Path::new("does not exist"); + + symlink_file(not_exist, &original).unwrap(); + fs::rename(&original, &dest).unwrap(); + // Make sure that renaming `original` to `dest` preserves the symlink. + assert_eq!(fs::read_link(&dest).unwrap().as_path(), not_exist); +} + +#[test] +#[cfg(windows)] +fn test_rename_junction() { + let tmpdir = tmpdir(); + let original = tmpdir.join("original"); + let dest = tmpdir.join("dest"); + let not_exist = Path::new("does not exist"); + + junction_point(¬_exist, &original).unwrap(); + fs::rename(&original, &dest).unwrap(); + + // Make sure that renaming `original` to `dest` preserves the junction point. + // Junction links are always absolute so we just check the file name is correct. + assert_eq!(fs::read_link(&dest).unwrap().file_name(), Some(not_exist.as_os_str())); +} diff --git a/std/src/io/buffered/bufreader/buffer.rs b/std/src/io/buffered/bufreader/buffer.rs index 52fe49985c65a..5251cc302cb49 100644 --- a/std/src/io/buffered/bufreader/buffer.rs +++ b/std/src/io/buffered/bufreader/buffer.rs @@ -41,7 +41,7 @@ impl Buffer { match Box::try_new_uninit_slice(capacity) { Ok(buf) => Ok(Self { buf, pos: 0, filled: 0, initialized: 0 }), Err(_) => { - Err(io::const_io_error!(ErrorKind::OutOfMemory, "failed to allocate read buffer")) + Err(io::const_error!(ErrorKind::OutOfMemory, "failed to allocate read buffer")) } } } @@ -50,7 +50,7 @@ impl Buffer { pub fn buffer(&self) -> &[u8] { // SAFETY: self.pos and self.cap are valid, and self.cap => self.pos, and // that region is initialized because those are all invariants of this type. - unsafe { MaybeUninit::slice_assume_init_ref(self.buf.get_unchecked(self.pos..self.filled)) } + unsafe { self.buf.get_unchecked(self.pos..self.filled).assume_init_ref() } } #[inline] diff --git a/std/src/io/buffered/bufwriter.rs b/std/src/io/buffered/bufwriter.rs index c41bae2aa4e81..574eb83dc5649 100644 --- a/std/src/io/buffered/bufwriter.rs +++ b/std/src/io/buffered/bufwriter.rs @@ -96,7 +96,7 @@ impl BufWriter { pub(crate) fn try_new_buffer() -> io::Result> { Vec::try_with_capacity(DEFAULT_BUF_SIZE).map_err(|_| { - io::const_io_error!(ErrorKind::OutOfMemory, "failed to allocate write buffer") + io::const_error!(ErrorKind::OutOfMemory, "failed to allocate write buffer") }) } @@ -238,7 +238,7 @@ impl BufWriter { match r { Ok(0) => { - return Err(io::const_io_error!( + return Err(io::const_error!( ErrorKind::WriteZero, "failed to write the buffered data", )); diff --git a/std/src/io/buffered/linewritershim.rs b/std/src/io/buffered/linewritershim.rs index 3d04ccd1c7d81..5ebeada59bb53 100644 --- a/std/src/io/buffered/linewritershim.rs +++ b/std/src/io/buffered/linewritershim.rs @@ -119,7 +119,14 @@ impl<'a, W: ?Sized + Write> Write for LineWriterShim<'a, W> { // the buffer? // - If not, scan for the last newline that *does* fit in the buffer let tail = if flushed >= newline_idx { - &buf[flushed..] + let tail = &buf[flushed..]; + // Avoid unnecessary short writes by not splitting the remaining + // bytes if they're larger than the buffer. + // They can be written in full by the next call to write. + if tail.len() >= self.buffer.capacity() { + return Ok(flushed); + } + tail } else if newline_idx - flushed <= self.buffer.capacity() { &buf[flushed..newline_idx] } else { diff --git a/std/src/io/buffered/tests.rs b/std/src/io/buffered/tests.rs index bff0f823c4b5a..17f6107aa030c 100644 --- a/std/src/io/buffered/tests.rs +++ b/std/src/io/buffered/tests.rs @@ -847,8 +847,7 @@ fn long_line_flushed() { } /// Test that, given a very long partial line *after* successfully -/// flushing a complete line, the very long partial line is buffered -/// unconditionally, and no additional writes take place. This assures +/// flushing a complete line, no additional writes take place. This assures /// the property that `write` should make at-most-one attempt to write /// new data. #[test] @@ -856,13 +855,22 @@ fn line_long_tail_not_flushed() { let writer = ProgrammableSink::default(); let mut writer = LineWriter::with_capacity(5, writer); - // Assert that Line 1\n is flushed, and 01234 is buffered - assert_eq!(writer.write(b"Line 1\n0123456789").unwrap(), 12); + // Assert that Line 1\n is flushed and the long tail isn't. + let bytes = b"Line 1\n0123456789"; + writer.write(bytes).unwrap(); assert_eq!(&writer.get_ref().buffer, b"Line 1\n"); +} + +// Test that appending to a full buffer emits a single write, flushing the buffer. +#[test] +fn line_full_buffer_flushed() { + let writer = ProgrammableSink::default(); + let mut writer = LineWriter::with_capacity(5, writer); + assert_eq!(writer.write(b"01234").unwrap(), 5); // Because the buffer is full, this subsequent write will flush it assert_eq!(writer.write(b"5").unwrap(), 1); - assert_eq!(&writer.get_ref().buffer, b"Line 1\n01234"); + assert_eq!(&writer.get_ref().buffer, b"01234"); } /// Test that, if an attempt to pre-flush buffered data returns Ok(0), diff --git a/std/src/io/cursor.rs b/std/src/io/cursor.rs index fbfdb4fa02323..b2ffeb0f95d0d 100644 --- a/std/src/io/cursor.rs +++ b/std/src/io/cursor.rs @@ -304,7 +304,7 @@ where self.pos = n; Ok(self.pos) } - None => Err(io::const_io_error!( + None => Err(io::const_error!( ErrorKind::InvalidInput, "invalid seek to a negative or overflowing position", )), @@ -446,7 +446,7 @@ fn reserve_and_pad( buf_len: usize, ) -> io::Result { let pos: usize = (*pos_mut).try_into().map_err(|_| { - io::const_io_error!( + io::const_error!( ErrorKind::InvalidInput, "cursor position exceeds maximum possible vector length", ) diff --git a/std/src/io/error.rs b/std/src/io/error.rs index 5d7adcace5247..38b723366175f 100644 --- a/std/src/io/error.rs +++ b/std/src/io/error.rs @@ -76,31 +76,31 @@ impl fmt::Debug for Error { #[allow(dead_code)] impl Error { pub(crate) const INVALID_UTF8: Self = - const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8"); + const_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8"); pub(crate) const READ_EXACT_EOF: Self = - const_io_error!(ErrorKind::UnexpectedEof, "failed to fill whole buffer"); + const_error!(ErrorKind::UnexpectedEof, "failed to fill whole buffer"); - pub(crate) const UNKNOWN_THREAD_COUNT: Self = const_io_error!( + pub(crate) const UNKNOWN_THREAD_COUNT: Self = const_error!( ErrorKind::NotFound, "The number of hardware threads is not known for the target platform" ); pub(crate) const UNSUPPORTED_PLATFORM: Self = - const_io_error!(ErrorKind::Unsupported, "operation not supported on this platform"); + const_error!(ErrorKind::Unsupported, "operation not supported on this platform"); pub(crate) const WRITE_ALL_EOF: Self = - const_io_error!(ErrorKind::WriteZero, "failed to write whole buffer"); + const_error!(ErrorKind::WriteZero, "failed to write whole buffer"); pub(crate) const ZERO_TIMEOUT: Self = - const_io_error!(ErrorKind::InvalidInput, "cannot set a 0 duration timeout"); + const_error!(ErrorKind::InvalidInput, "cannot set a 0 duration timeout"); } #[stable(feature = "rust1", since = "1.0.0")] impl From for Error { /// Converts a [`alloc::ffi::NulError`] into a [`Error`]. fn from(_: alloc::ffi::NulError) -> Error { - const_io_error!(ErrorKind::InvalidInput, "data provided contains a nul byte") + const_error!(ErrorKind::InvalidInput, "data provided contains a nul byte") } } @@ -151,27 +151,38 @@ pub type RawOsError = sys::RawOsError; // (For the sake of being explicit: the alignment requirement here only matters // if `error/repr_bitpacked.rs` is in use — for the unpacked repr it doesn't // matter at all) +#[doc(hidden)] +#[unstable(feature = "io_const_error_internals", issue = "none")] #[repr(align(4))] #[derive(Debug)] -pub(crate) struct SimpleMessage { - kind: ErrorKind, - message: &'static str, +pub struct SimpleMessage { + pub kind: ErrorKind, + pub message: &'static str, } -impl SimpleMessage { - pub(crate) const fn new(kind: ErrorKind, message: &'static str) -> Self { - Self { kind, message } - } -} - -/// Creates and returns an `io::Error` for a given `ErrorKind` and constant -/// message. This doesn't allocate. -pub(crate) macro const_io_error($kind:expr, $message:expr $(,)?) { - $crate::io::error::Error::from_static_message({ - const MESSAGE_DATA: $crate::io::error::SimpleMessage = - $crate::io::error::SimpleMessage::new($kind, $message); - &MESSAGE_DATA - }) +/// Creates a new I/O error from a known kind of error and a string literal. +/// +/// Contrary to [`Error::new`], this macro does not allocate and can be used in +/// `const` contexts. +/// +/// # Example +/// ``` +/// #![feature(io_const_error)] +/// use std::io::{const_error, Error, ErrorKind}; +/// +/// const FAIL: Error = const_error!(ErrorKind::Unsupported, "tried something that never works"); +/// +/// fn not_here() -> Result<(), Error> { +/// Err(FAIL) +/// } +/// ``` +#[rustc_macro_transparency = "semitransparent"] +#[unstable(feature = "io_const_error", issue = "133448")] +#[allow_internal_unstable(hint_must_use, io_const_error_internals)] +pub macro const_error($kind:expr, $message:expr $(,)?) { + $crate::hint::must_use($crate::io::Error::from_static_message( + const { &$crate::io::SimpleMessage { kind: $kind, message: $message } }, + )) } // As with `SimpleMessage`: `#[repr(align(4))]` here is just because @@ -327,9 +338,9 @@ pub enum ErrorKind { /// example, on Unix, a named pipe opened with `File::open`. #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] NotSeekable, - /// Filesystem quota was exceeded. - #[unstable(feature = "io_error_more", issue = "86442")] - FilesystemQuotaExceeded, + /// Filesystem quota or some other kind of quota was exceeded. + #[stable(feature = "io_error_quota_exceeded", since = "1.85.0")] + QuotaExceeded, /// File larger than allowed or supported. /// /// This might arise from a hard limit of the underlying filesystem or file access API, or from @@ -353,7 +364,7 @@ pub enum ErrorKind { #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] Deadlock, /// Cross-device or cross-filesystem (hard) link or rename. - #[unstable(feature = "io_error_more", issue = "86442")] + #[stable(feature = "io_error_crosses_devices", since = "1.85.0")] CrossesDevices, /// Too many (hard) links to the same filesystem object. /// @@ -435,8 +446,8 @@ pub enum ErrorKind { impl ErrorKind { pub(crate) fn as_str(&self) -> &'static str { use ErrorKind::*; - // tidy-alphabetical-start match *self { + // tidy-alphabetical-start AddrInUse => "address in use", AddrNotAvailable => "address not available", AlreadyExists => "entity already exists", @@ -449,12 +460,11 @@ impl ErrorKind { Deadlock => "deadlock", DirectoryNotEmpty => "directory not empty", ExecutableFileBusy => "executable file busy", - FileTooLarge => "file too large", FilesystemLoop => "filesystem loop or indirection limit (e.g. symlink loop)", - FilesystemQuotaExceeded => "filesystem quota exceeded", + FileTooLarge => "file too large", HostUnreachable => "host unreachable", - Interrupted => "operation interrupted", InProgress => "in progress", + Interrupted => "operation interrupted", InvalidData => "invalid data", InvalidFilename => "invalid filename", InvalidInput => "invalid input parameter", @@ -468,6 +478,7 @@ impl ErrorKind { Other => "other error", OutOfMemory => "out of memory", PermissionDenied => "permission denied", + QuotaExceeded => "quota exceeded", ReadOnlyFilesystem => "read-only filesystem or storage medium", ResourceBusy => "resource busy", StaleNetworkFileHandle => "stale network file handle", @@ -479,8 +490,8 @@ impl ErrorKind { Unsupported => "unsupported", WouldBlock => "operation would block", WriteZero => "write zero", + // tidy-alphabetical-end } - // tidy-alphabetical-end } } @@ -592,13 +603,15 @@ impl Error { /// /// This function does not allocate. /// - /// You should not use this directly, and instead use the `const_io_error!` - /// macro: `io::const_io_error!(ErrorKind::Something, "some_message")`. + /// You should not use this directly, and instead use the `const_error!` + /// macro: `io::const_error!(ErrorKind::Something, "some_message")`. /// /// This function should maybe change to `from_static_message(kind: ErrorKind)` in the future, when const generics allow that. #[inline] - pub(crate) const fn from_static_message(msg: &'static SimpleMessage) -> Error { + #[doc(hidden)] + #[unstable(feature = "io_const_error_internals", issue = "none")] + pub const fn from_static_message(msg: &'static SimpleMessage) -> Error { Self { repr: Repr::new_simple_message(msg) } } diff --git a/std/src/io/error/repr_bitpacked.rs b/std/src/io/error/repr_bitpacked.rs index a839a2fbac117..716da37168d01 100644 --- a/std/src/io/error/repr_bitpacked.rs +++ b/std/src/io/error/repr_bitpacked.rs @@ -103,7 +103,8 @@ //! the time. use core::marker::PhantomData; -use core::ptr::{self, NonNull}; +use core::num::NonZeroUsize; +use core::ptr::NonNull; use super::{Custom, ErrorData, ErrorKind, RawOsError, SimpleMessage}; @@ -176,7 +177,7 @@ impl Repr { let utagged = ((code as usize) << 32) | TAG_OS; // Safety: `TAG_OS` is not zero, so the result of the `|` is not 0. let res = Self( - unsafe { NonNull::new_unchecked(ptr::without_provenance_mut(utagged)) }, + NonNull::without_provenance(unsafe { NonZeroUsize::new_unchecked(utagged) }), PhantomData, ); // quickly smoke-check we encoded the right thing (This generally will @@ -193,7 +194,7 @@ impl Repr { let utagged = ((kind as usize) << 32) | TAG_SIMPLE; // Safety: `TAG_SIMPLE` is not zero, so the result of the `|` is not 0. let res = Self( - unsafe { NonNull::new_unchecked(ptr::without_provenance_mut(utagged)) }, + NonNull::without_provenance(unsafe { NonZeroUsize::new_unchecked(utagged) }), PhantomData, ); // quickly smoke-check we encoded the right thing (This generally will @@ -335,7 +336,7 @@ fn kind_from_prim(ek: u32) -> Option { WriteZero, StorageFull, NotSeekable, - FilesystemQuotaExceeded, + QuotaExceeded, FileTooLarge, ResourceBusy, ExecutableFileBusy, diff --git a/std/src/io/error/tests.rs b/std/src/io/error/tests.rs index 00d04984a3854..edac6563478cd 100644 --- a/std/src/io/error/tests.rs +++ b/std/src/io/error/tests.rs @@ -1,4 +1,4 @@ -use super::{Custom, Error, ErrorData, ErrorKind, Repr, SimpleMessage, const_io_error}; +use super::{Custom, Error, ErrorData, ErrorKind, Repr, SimpleMessage, const_error}; use crate::assert_matches::assert_matches; use crate::mem::size_of; use crate::sys::decode_error_kind; @@ -60,7 +60,7 @@ fn test_downcasting() { #[test] fn test_const() { - const E: Error = const_io_error!(ErrorKind::NotFound, "hello"); + const E: Error = const_error!(ErrorKind::NotFound, "hello"); assert_eq!(E.kind(), ErrorKind::NotFound); assert_eq!(E.to_string(), "hello"); @@ -110,13 +110,13 @@ fn test_simple_message_packing() { }}; } - let not_static = const_io_error!(Uncategorized, "not a constant!"); + let not_static = const_error!(Uncategorized, "not a constant!"); check_simple_msg!(not_static, Uncategorized, "not a constant!"); - const CONST: Error = const_io_error!(NotFound, "definitely a constant!"); + const CONST: Error = const_error!(NotFound, "definitely a constant!"); check_simple_msg!(CONST, NotFound, "definitely a constant!"); - static STATIC: Error = const_io_error!(BrokenPipe, "a constant, sort of!"); + static STATIC: Error = const_error!(BrokenPipe, "a constant, sort of!"); check_simple_msg!(STATIC, BrokenPipe, "a constant, sort of!"); } diff --git a/std/src/io/mod.rs b/std/src/io/mod.rs index 21e7077495450..7912f969bbd9f 100644 --- a/std/src/io/mod.rs +++ b/std/src/io/mod.rs @@ -301,12 +301,15 @@ mod tests; pub use core::io::{BorrowedBuf, BorrowedCursor}; use core::slice::memchr; -pub(crate) use error::const_io_error; - #[stable(feature = "bufwriter_into_parts", since = "1.56.0")] pub use self::buffered::WriterPanicked; #[unstable(feature = "raw_os_error_ty", issue = "107792")] pub use self::error::RawOsError; +#[doc(hidden)] +#[unstable(feature = "io_const_error_internals", issue = "none")] +pub use self::error::SimpleMessage; +#[unstable(feature = "io_const_error", issue = "133448")] +pub use self::error::const_error; #[stable(feature = "is_terminal", since = "1.70.0")] pub use self::stdio::IsTerminal; pub(crate) use self::stdio::attempt_print_to_stderr; @@ -1080,7 +1083,7 @@ pub trait Read { /// let f = BufReader::new(File::open("foo.txt")?); /// /// for byte in f.bytes() { - /// println!("{}", byte.unwrap()); + /// println!("{}", byte?); /// } /// Ok(()) /// } @@ -1992,15 +1995,16 @@ pub trait Seek { /// .write(true) /// .read(true) /// .create(true) - /// .open("foo.txt").unwrap(); + /// .open("foo.txt")?; /// /// let hello = "Hello!\n"; - /// write!(f, "{hello}").unwrap(); - /// f.rewind().unwrap(); + /// write!(f, "{hello}")?; + /// f.rewind()?; /// /// let mut buf = String::new(); - /// f.read_to_string(&mut buf).unwrap(); + /// f.read_to_string(&mut buf)?; /// assert_eq!(&buf, hello); + /// # std::io::Result::Ok(()) /// ``` #[stable(feature = "seek_rewind", since = "1.55.0")] fn rewind(&mut self) -> Result<()> { @@ -2209,8 +2213,9 @@ fn skip_until(r: &mut R, delim: u8) -> Result { /// /// let stdin = io::stdin(); /// for line in stdin.lock().lines() { -/// println!("{}", line.unwrap()); +/// println!("{}", line?); /// } +/// # std::io::Result::Ok(()) /// ``` /// /// If you have something that implements [`Read`], you can use the [`BufReader` @@ -2233,7 +2238,8 @@ fn skip_until(r: &mut R, delim: u8) -> Result { /// let f = BufReader::new(f); /// /// for line in f.lines() { -/// println!("{}", line.unwrap()); +/// let line = line?; +/// println!("{line}"); /// } /// /// Ok(()) @@ -2271,7 +2277,7 @@ pub trait BufRead: Read { /// let stdin = io::stdin(); /// let mut stdin = stdin.lock(); /// - /// let buffer = stdin.fill_buf().unwrap(); + /// let buffer = stdin.fill_buf()?; /// /// // work with buffer /// println!("{buffer:?}"); @@ -2279,6 +2285,7 @@ pub trait BufRead: Read { /// // ensure the bytes we worked with aren't returned again later /// let length = buffer.len(); /// stdin.consume(length); + /// # std::io::Result::Ok(()) /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn fill_buf(&mut self) -> Result<&[u8]>; @@ -2324,12 +2331,13 @@ pub trait BufRead: Read { /// let stdin = io::stdin(); /// let mut stdin = stdin.lock(); /// - /// while stdin.has_data_left().unwrap() { + /// while stdin.has_data_left()? { /// let mut line = String::new(); - /// stdin.read_line(&mut line).unwrap(); + /// stdin.read_line(&mut line)?; /// // work with line /// println!("{line:?}"); /// } + /// # std::io::Result::Ok(()) /// ``` #[unstable(feature = "buf_read_has_data_left", reason = "recently added", issue = "86423")] fn has_data_left(&mut self) -> Result { diff --git a/std/src/io/stdio.rs b/std/src/io/stdio.rs index 35b38ed783ff2..318c350822168 100644 --- a/std/src/io/stdio.rs +++ b/std/src/io/stdio.rs @@ -1200,6 +1200,7 @@ pub trait IsTerminal: crate::sealed::Sealed { /// /// [changes]: io#platform-specific-behavior /// [`Stdin`]: crate::io::Stdin + #[doc(alias = "isatty")] #[stable(feature = "is_terminal", since = "1.70.0")] fn is_terminal(&self) -> bool; } diff --git a/std/src/io/tests.rs b/std/src/io/tests.rs index 89e806c08911c..47cbb9614afdd 100644 --- a/std/src/io/tests.rs +++ b/std/src/io/tests.rs @@ -225,12 +225,12 @@ fn take_eof() { impl Read for R { fn read(&mut self, _: &mut [u8]) -> io::Result { - Err(io::const_io_error!(io::ErrorKind::Other, "")) + Err(io::const_error!(io::ErrorKind::Other, "")) } } impl BufRead for R { fn fill_buf(&mut self) -> io::Result<&[u8]> { - Err(io::const_io_error!(io::ErrorKind::Other, "")) + Err(io::const_error!(io::ErrorKind::Other, "")) } fn consume(&mut self, _amt: usize) {} } diff --git a/std/src/keyword_docs.rs b/std/src/keyword_docs.rs index 4302e24781ee8..0c526eafdf36f 100644 --- a/std/src/keyword_docs.rs +++ b/std/src/keyword_docs.rs @@ -807,64 +807,6 @@ mod in_keyword {} /// [Reference]: ../reference/statements.html#let-statements mod let_keyword {} -#[doc(keyword = "while")] -// -/// Loop while a condition is upheld. -/// -/// A `while` expression is used for predicate loops. The `while` expression runs the conditional -/// expression before running the loop body, then runs the loop body if the conditional -/// expression evaluates to `true`, or exits the loop otherwise. -/// -/// ```rust -/// let mut counter = 0; -/// -/// while counter < 10 { -/// println!("{counter}"); -/// counter += 1; -/// } -/// ``` -/// -/// Like the [`for`] expression, we can use `break` and `continue`. A `while` expression -/// cannot break with a value and always evaluates to `()` unlike [`loop`]. -/// -/// ```rust -/// let mut i = 1; -/// -/// while i < 100 { -/// i *= 2; -/// if i == 64 { -/// break; // Exit when `i` is 64. -/// } -/// } -/// ``` -/// -/// As `if` expressions have their pattern matching variant in `if let`, so too do `while` -/// expressions with `while let`. The `while let` expression matches the pattern against the -/// expression, then runs the loop body if pattern matching succeeds, or exits the loop otherwise. -/// We can use `break` and `continue` in `while let` expressions just like in `while`. -/// -/// ```rust -/// let mut counter = Some(0); -/// -/// while let Some(i) = counter { -/// if i == 10 { -/// counter = None; -/// } else { -/// println!("{i}"); -/// counter = Some (i + 1); -/// } -/// } -/// ``` -/// -/// For more information on `while` and loops in general, see the [reference]. -/// -/// See also, [`for`], [`loop`]. -/// -/// [`for`]: keyword.for.html -/// [`loop`]: keyword.loop.html -/// [reference]: ../reference/expressions/loop-expr.html#predicate-loops -mod while_keyword {} - #[doc(keyword = "loop")] // /// Loop indefinitely. @@ -1321,10 +1263,10 @@ mod return_keyword {} /// [Reference]: ../reference/items/associated-items.html#methods mod self_keyword {} -// FIXME: Once rustdoc can handle URL conflicts on case insensitive file systems, we can remove the -// three next lines and put back: `#[doc(keyword = "Self")]`. +// FIXME: Once rustdoc can handle URL conflicts on case insensitive file systems, we can replace +// these two lines with `#[doc(keyword = "Self")]` and update `is_doc_keyword` in +// `CheckAttrVisitor`. #[doc(alias = "Self")] -#[allow(rustc::existing_doc_keyword)] #[doc(keyword = "SelfTy")] // /// The implementing type within a [`trait`] or [`impl`] block, or the current type within a type @@ -2343,6 +2285,64 @@ mod use_keyword {} /// [RFC]: https://github.com/rust-lang/rfcs/blob/master/text/0135-where.md mod where_keyword {} +#[doc(keyword = "while")] +// +/// Loop while a condition is upheld. +/// +/// A `while` expression is used for predicate loops. The `while` expression runs the conditional +/// expression before running the loop body, then runs the loop body if the conditional +/// expression evaluates to `true`, or exits the loop otherwise. +/// +/// ```rust +/// let mut counter = 0; +/// +/// while counter < 10 { +/// println!("{counter}"); +/// counter += 1; +/// } +/// ``` +/// +/// Like the [`for`] expression, we can use `break` and `continue`. A `while` expression +/// cannot break with a value and always evaluates to `()` unlike [`loop`]. +/// +/// ```rust +/// let mut i = 1; +/// +/// while i < 100 { +/// i *= 2; +/// if i == 64 { +/// break; // Exit when `i` is 64. +/// } +/// } +/// ``` +/// +/// As `if` expressions have their pattern matching variant in `if let`, so too do `while` +/// expressions with `while let`. The `while let` expression matches the pattern against the +/// expression, then runs the loop body if pattern matching succeeds, or exits the loop otherwise. +/// We can use `break` and `continue` in `while let` expressions just like in `while`. +/// +/// ```rust +/// let mut counter = Some(0); +/// +/// while let Some(i) = counter { +/// if i == 10 { +/// counter = None; +/// } else { +/// println!("{i}"); +/// counter = Some (i + 1); +/// } +/// } +/// ``` +/// +/// For more information on `while` and loops in general, see the [reference]. +/// +/// See also, [`for`], [`loop`]. +/// +/// [`for`]: keyword.for.html +/// [`loop`]: keyword.loop.html +/// [reference]: ../reference/expressions/loop-expr.html#predicate-loops +mod while_keyword {} + // 2018 Edition keywords #[doc(alias = "promise")] diff --git a/std/src/lib.rs b/std/src/lib.rs index ee6fceb024fd7..5c12236617c98 100644 --- a/std/src/lib.rs +++ b/std/src/lib.rs @@ -89,7 +89,7 @@ //! Check out the Rust contribution guidelines [here]( //! https://rustc-dev-guide.rust-lang.org/contributing.html#writing-documentation). //! The source for this documentation can be found on -//! [GitHub](https://github.com/rust-lang/rust). +//! [GitHub](https://github.com/rust-lang/rust) in the 'library/std/' directory. //! To contribute changes, make sure you read the guidelines first, then submit //! pull-requests for your suggested changes. //! @@ -251,7 +251,6 @@ #![allow(explicit_outlives_requirements)] #![allow(unused_lifetimes)] #![allow(internal_features)] -#![deny(rustc::existing_doc_keyword)] #![deny(fuzzy_provenance_casts)] #![deny(unsafe_op_in_unsafe_fn)] #![allow(rustdoc::redundant_explicit_links)] @@ -262,7 +261,6 @@ #![allow(unused_features)] // // Features: -#![cfg_attr(not(bootstrap), feature(autodiff))] #![cfg_attr(test, feature(internal_output_capture, print_internals, update_panic_count, rt))] #![cfg_attr( all(target_vendor = "fortanix", target_env = "sgx"), @@ -274,13 +272,12 @@ // // Language features: // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(strict_provenance))] -#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))] #![feature(alloc_error_handler)] #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] #![feature(allow_internal_unstable)] #![feature(asm_experimental_arch)] +#![feature(autodiff)] #![feature(cfg_sanitizer_cfi)] #![feature(cfg_target_thread_local)] #![feature(cfi_encoding)] @@ -292,9 +289,9 @@ #![feature(doc_masked)] #![feature(doc_notable_trait)] #![feature(dropck_eyepatch)] -#![feature(extended_varargs_abi_support)] #![feature(f128)] #![feature(f16)] +#![feature(formatting_options)] #![feature(if_let_guard)] #![feature(intra_doc_pointers)] #![feature(lang_items)] @@ -314,6 +311,7 @@ #![feature(rustdoc_internals)] #![feature(staged_api)] #![feature(stmt_expr_attributes)] +#![feature(strict_provenance_lints)] #![feature(thread_local)] #![feature(try_blocks)] #![feature(type_alias_impl_trait)] @@ -322,7 +320,6 @@ // Library features (core): // tidy-alphabetical-start #![feature(array_chunks)] -#![feature(build_hasher_default_const_new)] #![feature(c_str_module)] #![feature(char_internals)] #![feature(clone_to_uninit)] @@ -340,16 +337,17 @@ #![feature(fmt_internals)] #![feature(hasher_prefixfree_extras)] #![feature(hashmap_internals)] +#![feature(hint_must_use)] #![feature(ip)] #![feature(lazy_get)] #![feature(maybe_uninit_slice)] #![feature(maybe_uninit_write_slice)] +#![feature(nonnull_provenance)] #![feature(panic_can_unwind)] #![feature(panic_internals)] #![feature(pin_coerce_unsized_trait)] #![feature(pointer_is_aligned_to)] #![feature(portable_simd)] -#![feature(prelude_2024)] #![feature(ptr_as_uninit)] #![feature(ptr_mask)] #![feature(random)] @@ -360,7 +358,9 @@ #![feature(str_internals)] #![feature(strict_provenance_atomic_ptr)] #![feature(sync_unsafe_cell)] +#![feature(temporary_niche_types)] #![feature(ub_checks)] +#![feature(used_with_arg)] // tidy-alphabetical-end // // Library features (alloc): @@ -374,6 +374,7 @@ #![feature(thin_box)] #![feature(try_reserve_kind)] #![feature(try_with_capacity)] +#![feature(unique_rc_arc)] #![feature(vec_into_raw_parts)] // tidy-alphabetical-end // @@ -409,8 +410,7 @@ // // Only for const-ness: // tidy-alphabetical-start -#![feature(const_collections_with_hasher)] -#![feature(thread_local_internals)] +#![feature(io_const_error)] // tidy-alphabetical-end // #![default_lib_allocator] @@ -546,6 +546,8 @@ pub use core::u64; #[stable(feature = "i128", since = "1.26.0")] #[allow(deprecated, deprecated_in_future)] pub use core::u128; +#[unstable(feature = "unsafe_binders", issue = "130516")] +pub use core::unsafe_binder; #[stable(feature = "rust1", since = "1.0.0")] #[allow(deprecated, deprecated_in_future)] pub use core::usize; @@ -591,7 +593,7 @@ pub mod net; pub mod num; pub mod os; pub mod panic; -#[unstable(feature = "core_pattern_types", issue = "123646")] +#[unstable(feature = "pattern_type_macro", issue = "123646")] pub mod pat; pub mod path; #[unstable(feature = "anonymous_pipe", issue = "127154")] @@ -620,7 +622,6 @@ pub mod simd { #[doc(inline)] pub use crate::std_float::StdFloat; } -#[cfg(not(bootstrap))] #[unstable(feature = "autodiff", issue = "124509")] /// This module provides support for automatic differentiation. pub mod autodiff { diff --git a/std/src/net/mod.rs b/std/src/net/mod.rs index 3b19c743b1e24..ddd3b68dd2d63 100644 --- a/std/src/net/mod.rs +++ b/std/src/net/mod.rs @@ -84,6 +84,6 @@ where } } Err(last_err.unwrap_or_else(|| { - io::const_io_error!(ErrorKind::InvalidInput, "could not resolve to any addresses") + io::const_error!(ErrorKind::InvalidInput, "could not resolve to any addresses") })) } diff --git a/std/src/net/udp.rs b/std/src/net/udp.rs index 6df47d7b0e0cd..674c5fb7d6ea3 100644 --- a/std/src/net/udp.rs +++ b/std/src/net/udp.rs @@ -203,9 +203,7 @@ impl UdpSocket { pub fn send_to(&self, buf: &[u8], addr: A) -> io::Result { match addr.to_socket_addrs()?.next() { Some(addr) => self.0.send_to(buf, &addr), - None => { - Err(io::const_io_error!(ErrorKind::InvalidInput, "no addresses to send data to")) - } + None => Err(io::const_error!(ErrorKind::InvalidInput, "no addresses to send data to")), } } diff --git a/std/src/os/darwin/mod.rs b/std/src/os/darwin/mod.rs index 7a057ddb861b7..3b1bd974fa313 100644 --- a/std/src/os/darwin/mod.rs +++ b/std/src/os/darwin/mod.rs @@ -13,7 +13,7 @@ //! `aarch64-apple-darwin` target names, which are mostly named that way for //! legacy reasons. -#![stable(feature = "os_darwin", since = "CURRENT_RUSTC_VERSION")] +#![stable(feature = "os_darwin", since = "1.84.0")] #![doc(cfg(target_vendor = "apple"))] pub mod fs; diff --git a/std/src/os/emscripten/fs.rs b/std/src/os/emscripten/fs.rs index 3282b79ac1c81..81f9ef331a5fa 100644 --- a/std/src/os/emscripten/fs.rs +++ b/std/src/os/emscripten/fs.rs @@ -63,7 +63,7 @@ pub trait MetadataExt { impl MetadataExt for Metadata { #[allow(deprecated)] fn as_raw_stat(&self) -> &raw::stat { - unsafe { &*(self.as_inner().as_inner() as *const libc::stat64 as *const raw::stat) } + unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) } } fn st_dev(&self) -> u64 { self.as_inner().as_inner().st_dev as u64 diff --git a/std/src/os/emscripten/raw.rs b/std/src/os/emscripten/raw.rs index d23011c738141..7ae8c45a6f80a 100644 --- a/std/src/os/emscripten/raw.rs +++ b/std/src/os/emscripten/raw.rs @@ -1,6 +1,4 @@ //! Emscripten-specific raw type definitions -//! This is basically exactly the same as the linux definitions, -//! except using the musl-specific stat64 structure in liblibc. #![stable(feature = "raw_ext", since = "1.1.0")] #![deprecated( diff --git a/std/src/os/fd/owned.rs b/std/src/os/fd/owned.rs index 388b8a88a1a48..1e814eca3c1a5 100644 --- a/std/src/os/fd/owned.rs +++ b/std/src/os/fd/owned.rs @@ -11,6 +11,8 @@ use crate::sys::cvt; use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::{fmt, fs, io}; +type ValidRawFd = core::num::niche_types::NotAllOnes; + /// A borrowed file descriptor. /// /// This has a lifetime parameter to tie it to the lifetime of something that owns the file @@ -32,15 +34,10 @@ use crate::{fmt, fs, io}; /// instead, but this is not supported on all platforms. #[derive(Copy, Clone)] #[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(0)] -// libstd/os/raw/mod.rs assures me that every libstd-supported platform has a -// 32-bit c_int. Below is -2, in two's complement, but that only works out -// because c_int is 32 bits. -#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] #[rustc_nonnull_optimization_guaranteed] #[stable(feature = "io_safety", since = "1.63.0")] pub struct BorrowedFd<'fd> { - fd: RawFd, + fd: ValidRawFd, _phantom: PhantomData<&'fd OwnedFd>, } @@ -56,15 +53,10 @@ pub struct BorrowedFd<'fd> { /// /// You can use [`AsFd::as_fd`] to obtain a [`BorrowedFd`]. #[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(0)] -// libstd/os/raw/mod.rs assures me that every libstd-supported platform has a -// 32-bit c_int. Below is -2, in two's complement, but that only works out -// because c_int is 32 bits. -#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] #[rustc_nonnull_optimization_guaranteed] #[stable(feature = "io_safety", since = "1.63.0")] pub struct OwnedFd { - fd: RawFd, + fd: ValidRawFd, } impl BorrowedFd<'_> { @@ -80,7 +72,8 @@ impl BorrowedFd<'_> { pub const unsafe fn borrow_raw(fd: RawFd) -> Self { assert!(fd != u32::MAX as RawFd); // SAFETY: we just asserted that the value is in the valid range and isn't `-1` (the only value bigger than `0xFF_FF_FF_FE` unsigned) - unsafe { Self { fd, _phantom: PhantomData } } + let fd = unsafe { ValidRawFd::new_unchecked(fd) }; + Self { fd, _phantom: PhantomData } } } @@ -130,7 +123,7 @@ impl BorrowedFd<'_> { impl AsRawFd for BorrowedFd<'_> { #[inline] fn as_raw_fd(&self) -> RawFd { - self.fd + self.fd.as_inner() } } @@ -138,7 +131,7 @@ impl AsRawFd for BorrowedFd<'_> { impl AsRawFd for OwnedFd { #[inline] fn as_raw_fd(&self) -> RawFd { - self.fd + self.fd.as_inner() } } @@ -146,7 +139,7 @@ impl AsRawFd for OwnedFd { impl IntoRawFd for OwnedFd { #[inline] fn into_raw_fd(self) -> RawFd { - ManuallyDrop::new(self).fd + ManuallyDrop::new(self).fd.as_inner() } } @@ -164,7 +157,8 @@ impl FromRawFd for OwnedFd { unsafe fn from_raw_fd(fd: RawFd) -> Self { assert_ne!(fd, u32::MAX as RawFd); // SAFETY: we just asserted that the value is in the valid range and isn't `-1` (the only value bigger than `0xFF_FF_FF_FE` unsigned) - unsafe { Self { fd } } + let fd = unsafe { ValidRawFd::new_unchecked(fd) }; + Self { fd } } } @@ -187,12 +181,12 @@ impl Drop for OwnedFd { #[cfg(not(target_os = "hermit"))] { #[cfg(unix)] - crate::sys::fs::debug_assert_fd_is_open(self.fd); + crate::sys::fs::debug_assert_fd_is_open(self.fd.as_inner()); - let _ = libc::close(self.fd); + let _ = libc::close(self.fd.as_inner()); } #[cfg(target_os = "hermit")] - let _ = hermit_abi::close(self.fd); + let _ = hermit_abi::close(self.fd.as_inner()); } } } @@ -428,6 +422,14 @@ impl AsFd for crate::rc::Rc { } } +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl AsFd for crate::rc::UniqueRc { + #[inline] + fn as_fd(&self) -> BorrowedFd<'_> { + (**self).as_fd() + } +} + #[stable(feature = "asfd_ptrs", since = "1.64.0")] impl AsFd for Box { #[inline] diff --git a/std/src/os/fd/raw.rs b/std/src/os/fd/raw.rs index 0d99d5492a268..22f5528248a32 100644 --- a/std/src/os/fd/raw.rs +++ b/std/src/os/fd/raw.rs @@ -266,6 +266,14 @@ impl AsRawFd for crate::rc::Rc { } } +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl AsRawFd for crate::rc::UniqueRc { + #[inline] + fn as_raw_fd(&self) -> RawFd { + (**self).as_raw_fd() + } +} + #[stable(feature = "asrawfd_ptrs", since = "1.63.0")] impl AsRawFd for Box { #[inline] diff --git a/std/src/os/hurd/fs.rs b/std/src/os/hurd/fs.rs index 00ff1560f31d9..e3087fa8af1cc 100644 --- a/std/src/os/hurd/fs.rs +++ b/std/src/os/hurd/fs.rs @@ -298,7 +298,7 @@ pub trait MetadataExt { #[stable(feature = "metadata_ext", since = "1.1.0")] impl MetadataExt for Metadata { fn st_dev(&self) -> u64 { - self.as_inner().as_inner().st_fsid as u64 + self.as_inner().as_inner().st_dev as u64 } fn st_ino(&self) -> u64 { self.as_inner().as_inner().st_ino as u64 diff --git a/std/src/os/hurd/mod.rs b/std/src/os/hurd/mod.rs index aee86c7f61655..6cd50aeada1da 100644 --- a/std/src/os/hurd/mod.rs +++ b/std/src/os/hurd/mod.rs @@ -1,6 +1,7 @@ //! Hurd-specific definitions #![stable(feature = "raw_ext", since = "1.1.0")] +#![forbid(unsafe_op_in_unsafe_fn)] pub mod fs; pub mod raw; diff --git a/std/src/os/solid/io.rs b/std/src/os/solid/io.rs index 2d18f33961506..b8601b533fe0d 100644 --- a/std/src/os/solid/io.rs +++ b/std/src/os/solid/io.rs @@ -54,6 +54,9 @@ use crate::{fmt, net, sys}; /// Raw file descriptors. pub type RawFd = i32; +// The max of this is -2, in two's complement. -1 is `SOLID_NET_INVALID_FD`. +type ValidRawFd = core::num::niche_types::NotAllOnes; + /// A borrowed SOLID Sockets file descriptor. /// /// This has a lifetime parameter to tie it to the lifetime of something that @@ -69,12 +72,9 @@ pub type RawFd = i32; /// socket, which is then borrowed under the same lifetime. #[derive(Copy, Clone)] #[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(0)] -// This is -2, in two's complement. -1 is `SOLID_NET_INVALID_FD`. -#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] #[rustc_nonnull_optimization_guaranteed] pub struct BorrowedFd<'socket> { - fd: RawFd, + fd: ValidRawFd, _phantom: PhantomData<&'socket OwnedFd>, } @@ -87,12 +87,9 @@ pub struct BorrowedFd<'socket> { /// an argument, it is not captured or consumed, and it never has the value /// `SOLID_NET_INVALID_FD`. #[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(0)] -// This is -2, in two's complement. -1 is `SOLID_NET_INVALID_FD`. -#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] #[rustc_nonnull_optimization_guaranteed] pub struct OwnedFd { - fd: RawFd, + fd: ValidRawFd, } impl BorrowedFd<'_> { @@ -108,7 +105,8 @@ impl BorrowedFd<'_> { assert!(fd != -1 as RawFd); // SAFETY: we just asserted that the value is in the valid range and // isn't `-1` (the only value bigger than `0xFF_FF_FF_FE` unsigned) - unsafe { Self { fd, _phantom: PhantomData } } + let fd = unsafe { ValidRawFd::new_unchecked(fd) }; + Self { fd, _phantom: PhantomData } } } @@ -132,21 +130,21 @@ impl BorrowedFd<'_> { impl AsRawFd for BorrowedFd<'_> { #[inline] fn as_raw_fd(&self) -> RawFd { - self.fd + self.fd.as_inner() } } impl AsRawFd for OwnedFd { #[inline] fn as_raw_fd(&self) -> RawFd { - self.fd + self.fd.as_inner() } } impl IntoRawFd for OwnedFd { #[inline] fn into_raw_fd(self) -> RawFd { - ManuallyDrop::new(self).fd + ManuallyDrop::new(self).fd.as_inner() } } @@ -162,14 +160,15 @@ impl FromRawFd for OwnedFd { assert_ne!(fd, -1 as RawFd); // SAFETY: we just asserted that the value is in the valid range and // isn't `-1` (the only value bigger than `0xFF_FF_FF_FE` unsigned) - unsafe { Self { fd } } + let fd = unsafe { ValidRawFd::new_unchecked(fd) }; + Self { fd } } } impl Drop for OwnedFd { #[inline] fn drop(&mut self) { - unsafe { sys::net::netc::close(self.fd) }; + unsafe { sys::net::netc::close(self.fd.as_inner()) }; } } diff --git a/std/src/os/unix/fs.rs b/std/src/os/unix/fs.rs index ba6481f052cdf..04a45fd035a55 100644 --- a/std/src/os/unix/fs.rs +++ b/std/src/os/unix/fs.rs @@ -987,6 +987,11 @@ impl DirBuilderExt for fs::DirBuilder { /// Changing the group typically requires either being the owner and a member of the group, or /// having privileges. /// +/// Be aware that changing owner clears the `suid` and `sgid` permission bits in most cases +/// according to POSIX, usually even if the user is root. The sgid is not cleared when +/// the file is non-group-executable. See: +/// This call may also clear file capabilities, if there was any. +/// /// If called on a symbolic link, this will change the owner and group of the link target. To /// change the owner and group of the link itself, see [`lchown`]. /// diff --git a/std/src/os/unix/net/addr.rs b/std/src/os/unix/net/addr.rs index 253e1503cf7af..56789f235fdab 100644 --- a/std/src/os/unix/net/addr.rs +++ b/std/src/os/unix/net/addr.rs @@ -30,14 +30,14 @@ pub(super) fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::s let bytes = path.as_os_str().as_bytes(); if bytes.contains(&0) { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "paths must not contain interior null bytes", )); } if bytes.len() >= addr.sun_path.len() { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "path must be shorter than SUN_LEN", )); @@ -119,7 +119,7 @@ impl SocketAddr { // linux returns zero bytes of address len = SUN_PATH_OFFSET as libc::socklen_t; // i.e., zero-length address } else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "file descriptor did not correspond to a Unix socket", )); @@ -273,7 +273,7 @@ impl linux_ext::addr::SocketAddrExt for SocketAddr { addr.sun_family = libc::AF_UNIX as libc::sa_family_t; if name.len() + 1 > addr.sun_path.len() { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "abstract socket name must be shorter than SUN_LEN", )); diff --git a/std/src/os/wasi/fs.rs b/std/src/os/wasi/fs.rs index 9ec3e387e2ba9..42aada131dadc 100644 --- a/std/src/os/wasi/fs.rs +++ b/std/src/os/wasi/fs.rs @@ -261,7 +261,7 @@ impl FileExt for fs::File { a if a == wasi::ADVICE_DONTNEED.raw() => wasi::ADVICE_DONTNEED, a if a == wasi::ADVICE_NOREUSE.raw() => wasi::ADVICE_NOREUSE, _ => { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "invalid parameter 'advice'", )); @@ -560,6 +560,5 @@ pub fn symlink_path, U: AsRef>(old_path: P, new_path: U) -> } fn osstr2str(f: &OsStr) -> io::Result<&str> { - f.to_str() - .ok_or_else(|| io::const_io_error!(io::ErrorKind::Uncategorized, "input must be utf-8")) + f.to_str().ok_or_else(|| io::const_error!(io::ErrorKind::Uncategorized, "input must be utf-8")) } diff --git a/std/src/os/windows/io/handle.rs b/std/src/os/windows/io/handle.rs index a4fa94e2b96a4..76f5f549dd244 100644 --- a/std/src/os/windows/io/handle.rs +++ b/std/src/os/windows/io/handle.rs @@ -485,6 +485,14 @@ impl AsHandle for crate::rc::Rc { } } +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl AsHandle for crate::rc::UniqueRc { + #[inline] + fn as_handle(&self) -> BorrowedHandle<'_> { + (**self).as_handle() + } +} + #[stable(feature = "as_windows_ptrs", since = "1.71.0")] impl AsHandle for Box { #[inline] diff --git a/std/src/os/windows/io/socket.rs b/std/src/os/windows/io/socket.rs index 1fcfb6e73ad03..6e13a8b502a73 100644 --- a/std/src/os/windows/io/socket.rs +++ b/std/src/os/windows/io/socket.rs @@ -9,6 +9,9 @@ use crate::mem::{self, ManuallyDrop}; use crate::sys::cvt; use crate::{fmt, io, sys}; +// The max here is -2, in two's complement. -1 is `INVALID_SOCKET`. +type ValidRawSocket = core::num::niche_types::NotAllOnes; + /// A borrowed socket. /// /// This has a lifetime parameter to tie it to the lifetime of something that @@ -24,17 +27,10 @@ use crate::{fmt, io, sys}; /// socket, which is then borrowed under the same lifetime. #[derive(Copy, Clone)] #[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(0)] -// This is -2, in two's complement. -1 is `INVALID_SOCKET`. -#[cfg_attr(target_pointer_width = "32", rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE))] -#[cfg_attr( - target_pointer_width = "64", - rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE) -)] #[rustc_nonnull_optimization_guaranteed] #[stable(feature = "io_safety", since = "1.63.0")] pub struct BorrowedSocket<'socket> { - socket: RawSocket, + socket: ValidRawSocket, _phantom: PhantomData<&'socket OwnedSocket>, } @@ -47,17 +43,10 @@ pub struct BorrowedSocket<'socket> { /// argument or returned as an owned value, and it never has the value /// `INVALID_SOCKET`. #[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(0)] -// This is -2, in two's complement. -1 is `INVALID_SOCKET`. -#[cfg_attr(target_pointer_width = "32", rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE))] -#[cfg_attr( - target_pointer_width = "64", - rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE) -)] #[rustc_nonnull_optimization_guaranteed] #[stable(feature = "io_safety", since = "1.63.0")] pub struct OwnedSocket { - socket: RawSocket, + socket: ValidRawSocket, } impl BorrowedSocket<'_> { @@ -73,7 +62,8 @@ impl BorrowedSocket<'_> { #[stable(feature = "io_safety", since = "1.63.0")] pub const unsafe fn borrow_raw(socket: RawSocket) -> Self { assert!(socket != sys::c::INVALID_SOCKET as RawSocket); - unsafe { Self { socket, _phantom: PhantomData } } + let socket = unsafe { ValidRawSocket::new_unchecked(socket) }; + Self { socket, _phantom: PhantomData } } } @@ -101,7 +91,7 @@ impl OwnedSocket { #[cfg(target_vendor = "uwp")] pub(crate) fn set_no_inherit(&self) -> io::Result<()> { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "Unavailable on UWP")) + Err(io::const_error!(io::ErrorKind::Unsupported, "Unavailable on UWP")) } } @@ -172,7 +162,7 @@ fn last_error() -> io::Error { impl AsRawSocket for BorrowedSocket<'_> { #[inline] fn as_raw_socket(&self) -> RawSocket { - self.socket + self.socket.as_inner() } } @@ -180,7 +170,7 @@ impl AsRawSocket for BorrowedSocket<'_> { impl AsRawSocket for OwnedSocket { #[inline] fn as_raw_socket(&self) -> RawSocket { - self.socket + self.socket.as_inner() } } @@ -188,7 +178,7 @@ impl AsRawSocket for OwnedSocket { impl IntoRawSocket for OwnedSocket { #[inline] fn into_raw_socket(self) -> RawSocket { - ManuallyDrop::new(self).socket + ManuallyDrop::new(self).socket.as_inner() } } @@ -196,10 +186,9 @@ impl IntoRawSocket for OwnedSocket { impl FromRawSocket for OwnedSocket { #[inline] unsafe fn from_raw_socket(socket: RawSocket) -> Self { - unsafe { - debug_assert_ne!(socket, sys::c::INVALID_SOCKET as RawSocket); - Self { socket } - } + debug_assert_ne!(socket, sys::c::INVALID_SOCKET as RawSocket); + let socket = unsafe { ValidRawSocket::new_unchecked(socket) }; + Self { socket } } } @@ -208,7 +197,7 @@ impl Drop for OwnedSocket { #[inline] fn drop(&mut self) { unsafe { - let _ = sys::c::closesocket(self.socket as sys::c::SOCKET); + let _ = sys::c::closesocket(self.socket.as_inner() as sys::c::SOCKET); } } } @@ -279,6 +268,14 @@ impl AsSocket for crate::rc::Rc { } } +#[unstable(feature = "unique_rc_arc", issue = "112566")] +impl AsSocket for crate::rc::UniqueRc { + #[inline] + fn as_socket(&self) -> BorrowedSocket<'_> { + (**self).as_socket() + } +} + #[stable(feature = "as_windows_ptrs", since = "1.71.0")] impl AsSocket for Box { #[inline] diff --git a/std/src/os/windows/process.rs b/std/src/os/windows/process.rs index c2830d2eb61d1..0277b79b8b69c 100644 --- a/std/src/os/windows/process.rs +++ b/std/src/os/windows/process.rs @@ -4,13 +4,14 @@ #![stable(feature = "process_extensions", since = "1.2.0")] -use crate::ffi::OsStr; +use crate::ffi::{OsStr, c_void}; +use crate::mem::MaybeUninit; use crate::os::windows::io::{ AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle, OwnedHandle, RawHandle, }; use crate::sealed::Sealed; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; -use crate::{process, sys}; +use crate::{io, marker, process, ptr, sys}; #[stable(feature = "process_extensions", since = "1.2.0")] impl FromRawHandle for process::Stdio { @@ -295,41 +296,25 @@ pub trait CommandExt: Sealed { #[unstable(feature = "windows_process_extensions_async_pipes", issue = "98289")] fn async_pipes(&mut self, always_async: bool) -> &mut process::Command; - /// Set a raw attribute on the command, providing extended configuration options for Windows - /// processes. + /// Executes the command as a child process with the given + /// [`ProcThreadAttributeList`], returning a handle to it. /// - /// This method allows you to specify custom attributes for a child process on Windows systems - /// using raw attribute values. Raw attributes provide extended configurability for process - /// creation, but their usage can be complex and potentially unsafe. - /// - /// The `attribute` parameter specifies the raw attribute to be set, while the `value` - /// parameter holds the value associated with that attribute. Please refer to the - /// [`windows-rs` documentation] or the [Win32 API documentation] for detailed information - /// about available attributes and their meanings. - /// - /// [`windows-rs` documentation]: https://microsoft.github.io/windows-docs-rs/doc/windows/ - /// [Win32 API documentation]: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-updateprocthreadattribute + /// This method enables the customization of attributes for the spawned + /// child process on Windows systems. + /// Attributes offer extended configurability for process creation, + /// but their usage can be intricate and potentially unsafe. /// /// # Note /// - /// The maximum number of raw attributes is the value of [`u32::MAX`]. - /// If this limit is exceeded, the call to [`process::Command::spawn`] will return an `Error` - /// indicating that the maximum number of attributes has been exceeded. - /// - /// # Safety - /// - /// The usage of raw attributes is potentially unsafe and should be done with caution. - /// Incorrect attribute values or improper configuration can lead to unexpected behavior or - /// errors. + /// By default, stdin, stdout, and stderr are inherited from the parent + /// process. /// /// # Example /// - /// The following example demonstrates how to create a child process with a specific parent - /// process ID using a raw attribute. - /// - /// ```rust + /// ``` /// #![feature(windows_process_extensions_raw_attribute)] - /// use std::os::windows::{process::CommandExt, io::AsRawHandle}; + /// use std::os::windows::io::AsRawHandle; + /// use std::os::windows::process::{CommandExt, ProcThreadAttributeList}; /// use std::process::Command; /// /// # struct ProcessDropGuard(std::process::Child); @@ -338,36 +323,27 @@ pub trait CommandExt: Sealed { /// # let _ = self.0.kill(); /// # } /// # } - /// + /// # /// let parent = Command::new("cmd").spawn()?; - /// - /// let mut child_cmd = Command::new("cmd"); + /// let parent_process_handle = parent.as_raw_handle(); + /// # let parent = ProcessDropGuard(parent); /// /// const PROC_THREAD_ATTRIBUTE_PARENT_PROCESS: usize = 0x00020000; + /// let mut attribute_list = ProcThreadAttributeList::build() + /// .attribute(PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &parent_process_handle) + /// .finish() + /// .unwrap(); /// - /// unsafe { - /// child_cmd.raw_attribute(PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, parent.as_raw_handle() as isize); - /// } + /// let mut child = Command::new("cmd").spawn_with_attributes(&attribute_list)?; /// # - /// # let parent = ProcessDropGuard(parent); - /// - /// let mut child = child_cmd.spawn()?; - /// /// # child.kill()?; /// # Ok::<(), std::io::Error>(()) /// ``` - /// - /// # Safety Note - /// - /// Remember that improper use of raw attributes can lead to undefined behavior or security - /// vulnerabilities. Always consult the documentation and ensure proper attribute values are - /// used. #[unstable(feature = "windows_process_extensions_raw_attribute", issue = "114854")] - unsafe fn raw_attribute( + fn spawn_with_attributes( &mut self, - attribute: usize, - value: T, - ) -> &mut process::Command; + attribute_list: &ProcThreadAttributeList<'_>, + ) -> io::Result; } #[stable(feature = "windows_process_extensions", since = "1.16.0")] @@ -401,13 +377,13 @@ impl CommandExt for process::Command { self } - unsafe fn raw_attribute( + fn spawn_with_attributes( &mut self, - attribute: usize, - value: T, - ) -> &mut process::Command { - unsafe { self.as_inner_mut().raw_attribute(attribute, value) }; - self + attribute_list: &ProcThreadAttributeList<'_>, + ) -> io::Result { + self.as_inner_mut() + .spawn_with_attributes(sys::process::Stdio::Inherit, true, Some(attribute_list)) + .map(process::Child::from_inner) } } @@ -447,3 +423,245 @@ impl ExitCodeExt for process::ExitCode { process::ExitCode::from_inner(From::from(raw)) } } + +/// A wrapper around windows [`ProcThreadAttributeList`][1]. +/// +/// [1]: +#[derive(Debug)] +#[unstable(feature = "windows_process_extensions_raw_attribute", issue = "114854")] +pub struct ProcThreadAttributeList<'a> { + attribute_list: Box<[MaybeUninit]>, + _lifetime_marker: marker::PhantomData<&'a ()>, +} + +#[unstable(feature = "windows_process_extensions_raw_attribute", issue = "114854")] +impl<'a> ProcThreadAttributeList<'a> { + /// Creates a new builder for constructing a [`ProcThreadAttributeList`]. + pub fn build() -> ProcThreadAttributeListBuilder<'a> { + ProcThreadAttributeListBuilder::new() + } + + /// Returns a pointer to the underling attribute list. + #[doc(hidden)] + pub fn as_ptr(&self) -> *const MaybeUninit { + self.attribute_list.as_ptr() + } +} + +#[unstable(feature = "windows_process_extensions_raw_attribute", issue = "114854")] +impl<'a> Drop for ProcThreadAttributeList<'a> { + /// Deletes the attribute list. + /// + /// This method calls [`DeleteProcThreadAttributeList`][1] to delete the + /// underlying attribute list. + /// + /// [1]: + fn drop(&mut self) { + let lp_attribute_list = self.attribute_list.as_mut_ptr().cast::(); + unsafe { sys::c::DeleteProcThreadAttributeList(lp_attribute_list) } + } +} + +/// Builder for constructing a [`ProcThreadAttributeList`]. +#[derive(Clone, Debug)] +#[unstable(feature = "windows_process_extensions_raw_attribute", issue = "114854")] +pub struct ProcThreadAttributeListBuilder<'a> { + attributes: alloc::collections::BTreeMap, + _lifetime_marker: marker::PhantomData<&'a ()>, +} + +#[unstable(feature = "windows_process_extensions_raw_attribute", issue = "114854")] +impl<'a> ProcThreadAttributeListBuilder<'a> { + fn new() -> Self { + ProcThreadAttributeListBuilder { + attributes: alloc::collections::BTreeMap::new(), + _lifetime_marker: marker::PhantomData, + } + } + + /// Sets an attribute on the attribute list. + /// + /// The `attribute` parameter specifies the raw attribute to be set, while + /// the `value` parameter holds the value associated with that attribute. + /// Please refer to the [Windows documentation][1] for a list of valid attributes. + /// + /// # Note + /// + /// The maximum number of attributes is the value of [`u32::MAX`]. If this + /// limit is exceeded, the call to [`Self::finish`] will return an `Error` + /// indicating that the maximum number of attributes has been exceeded. + /// + /// # Safety Note + /// + /// Remember that improper use of attributes can lead to undefined behavior + /// or security vulnerabilities. Always consult the documentation and ensure + /// proper attribute values are used. + /// + /// [1]: + pub fn attribute(self, attribute: usize, value: &'a T) -> Self { + unsafe { + self.raw_attribute( + attribute, + ptr::addr_of!(*value).cast::(), + crate::mem::size_of::(), + ) + } + } + + /// Sets a raw attribute on the attribute list. + /// + /// This function is useful for setting attributes with pointers or sizes + /// that cannot be derived directly from their values. + /// + /// # Safety + /// + /// This function is marked as `unsafe` because it deals with raw pointers + /// and sizes. It is the responsibility of the caller to ensure the value + /// lives longer than the resulting [`ProcThreadAttributeList`] as well as + /// the validity of the size parameter. + /// + /// # Example + /// + /// ``` + /// #![feature(windows_process_extensions_raw_attribute)] + /// use std::ffi::c_void; + /// use std::os::windows::process::{CommandExt, ProcThreadAttributeList}; + /// use std::os::windows::raw::HANDLE; + /// use std::process::Command; + /// + /// #[repr(C)] + /// pub struct COORD { + /// pub X: i16, + /// pub Y: i16, + /// } + /// + /// extern "system" { + /// fn CreatePipe( + /// hreadpipe: *mut HANDLE, + /// hwritepipe: *mut HANDLE, + /// lppipeattributes: *const c_void, + /// nsize: u32, + /// ) -> i32; + /// fn CreatePseudoConsole( + /// size: COORD, + /// hinput: HANDLE, + /// houtput: HANDLE, + /// dwflags: u32, + /// phpc: *mut isize, + /// ) -> i32; + /// fn CloseHandle(hobject: HANDLE) -> i32; + /// } + /// + /// let [mut input_read_side, mut output_write_side, mut output_read_side, mut input_write_side] = + /// [unsafe { std::mem::zeroed::() }; 4]; + /// + /// unsafe { + /// CreatePipe(&mut input_read_side, &mut input_write_side, std::ptr::null(), 0); + /// CreatePipe(&mut output_read_side, &mut output_write_side, std::ptr::null(), 0); + /// } + /// + /// let size = COORD { X: 60, Y: 40 }; + /// let mut h_pc = unsafe { std::mem::zeroed() }; + /// unsafe { CreatePseudoConsole(size, input_read_side, output_write_side, 0, &mut h_pc) }; + /// + /// unsafe { CloseHandle(input_read_side) }; + /// unsafe { CloseHandle(output_write_side) }; + /// + /// const PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE: usize = 131094; + /// + /// let attribute_list = unsafe { + /// ProcThreadAttributeList::build() + /// .raw_attribute( + /// PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, + /// h_pc as *const c_void, + /// std::mem::size_of::(), + /// ) + /// .finish()? + /// }; + /// + /// let mut child = Command::new("cmd").spawn_with_attributes(&attribute_list)?; + /// # + /// # child.kill()?; + /// # Ok::<(), std::io::Error>(()) + /// ``` + pub unsafe fn raw_attribute( + mut self, + attribute: usize, + value_ptr: *const T, + value_size: usize, + ) -> Self { + self.attributes.insert(attribute, ProcThreadAttributeValue { + ptr: value_ptr.cast::(), + size: value_size, + }); + self + } + + /// Finalizes the construction of the `ProcThreadAttributeList`. + /// + /// # Errors + /// + /// Returns an error if the maximum number of attributes is exceeded + /// or if there is an I/O error during initialization. + pub fn finish(&self) -> io::Result> { + // To initialize our ProcThreadAttributeList, we need to determine + // how many bytes to allocate for it. The Windows API simplifies this + // process by allowing us to call `InitializeProcThreadAttributeList` + // with a null pointer to retrieve the required size. + let mut required_size = 0; + let Ok(attribute_count) = self.attributes.len().try_into() else { + return Err(io::const_error!( + io::ErrorKind::InvalidInput, + "maximum number of ProcThreadAttributes exceeded", + )); + }; + unsafe { + sys::c::InitializeProcThreadAttributeList( + ptr::null_mut(), + attribute_count, + 0, + &mut required_size, + ) + }; + + let mut attribute_list = vec![MaybeUninit::uninit(); required_size].into_boxed_slice(); + + // Once we've allocated the necessary memory, it's safe to invoke + // `InitializeProcThreadAttributeList` to properly initialize the list. + sys::cvt(unsafe { + sys::c::InitializeProcThreadAttributeList( + attribute_list.as_mut_ptr().cast::(), + attribute_count, + 0, + &mut required_size, + ) + })?; + + // # Add our attributes to the buffer. + // It's theoretically possible for the attribute count to exceed a u32 + // value. Therefore, we ensure that we don't add more attributes than + // the buffer was initialized for. + for (&attribute, value) in self.attributes.iter().take(attribute_count as usize) { + sys::cvt(unsafe { + sys::c::UpdateProcThreadAttribute( + attribute_list.as_mut_ptr().cast::(), + 0, + attribute, + value.ptr, + value.size, + ptr::null_mut(), + ptr::null_mut(), + ) + })?; + } + + Ok(ProcThreadAttributeList { attribute_list, _lifetime_marker: marker::PhantomData }) + } +} + +/// Wrapper around the value data to be used as a Process Thread Attribute. +#[derive(Clone, Debug)] +struct ProcThreadAttributeValue { + ptr: *const c_void, + size: usize, +} diff --git a/std/src/panicking.rs b/std/src/panicking.rs index ac1f547c9143f..8e50bf11dd082 100644 --- a/std/src/panicking.rs +++ b/std/src/panicking.rs @@ -27,6 +27,22 @@ use crate::sys::backtrace; use crate::sys::stdio::panic_output; use crate::{fmt, intrinsics, process, thread}; +// This forces codegen of the function called by panic!() inside the std crate, rather than in +// downstream crates. Primarily this is useful for rustc's codegen tests, which rely on noticing +// complete removal of panic from generated IR. Since begin_panic is inline(never), it's only +// codegen'd once per crate-graph so this pushes that to std rather than our codegen test crates. +// +// (See https://github.com/rust-lang/rust/pull/123244 for more info on why). +// +// If this is causing problems we can also modify those codegen tests to use a crate type like +// cdylib which doesn't export "Rust" symbols to downstream linkage units. +#[unstable(feature = "libstd_sys_internals", reason = "used by the panic! macro", issue = "none")] +#[doc(hidden)] +#[allow(dead_code)] +#[used(compiler)] +pub static EMPTY_PANIC: fn(&'static str) -> ! = + begin_panic::<&'static str> as fn(&'static str) -> !; + // Binary interface to the panic runtime that the standard library depends on. // // The standard library is tagged with `#![needs_panic_runtime]` (introduced in @@ -65,7 +81,9 @@ extern "C" fn __rust_foreign_exception() -> ! { rtabort!("Rust cannot catch foreign exceptions"); } +#[derive(Default)] enum Hook { + #[default] Default, Custom(Box) + 'static + Sync + Send>), } @@ -80,13 +98,6 @@ impl Hook { } } -impl Default for Hook { - #[inline] - fn default() -> Hook { - Hook::Default - } -} - static HOOK: RwLock = RwLock::new(Hook::Default); /// Registers a custom panic hook, replacing the previously registered hook. @@ -247,15 +258,34 @@ fn default_hook(info: &PanicHookInfo<'_>) { let location = info.location().unwrap(); let msg = payload_as_str(info.payload()); - let thread = thread::try_current(); - let name = thread.as_ref().and_then(|t| t.name()).unwrap_or(""); let write = #[optimize(size)] |err: &mut dyn crate::io::Write| { // Use a lock to prevent mixed output in multithreading context. // Some platforms also require it when printing a backtrace, like `SymFromAddr` on Windows. let mut lock = backtrace::lock(); - let _ = writeln!(err, "thread '{name}' panicked at {location}:\n{msg}"); + + thread::with_current_name(|name| { + let name = name.unwrap_or(""); + + // Try to write the panic message to a buffer first to prevent other concurrent outputs + // interleaving with it. + let mut buffer = [0u8; 512]; + let mut cursor = crate::io::Cursor::new(&mut buffer[..]); + + let write_msg = |dst: &mut dyn crate::io::Write| { + // We add a newline to ensure the panic message appears at the start of a line. + writeln!(dst, "\nthread '{name}' panicked at {location}:\n{msg}") + }; + + if write_msg(&mut cursor).is_ok() { + let pos = cursor.position() as usize; + let _ = err.write_all(&buffer[0..pos]); + } else { + // The message did not fit into the buffer, write it directly instead. + let _ = write_msg(err); + }; + }); static FIRST_PANIC: AtomicBool = AtomicBool::new(true); @@ -607,7 +637,7 @@ pub fn begin_panic_handler(info: &core::panic::PanicInfo<'_>) -> ! { // Lazily, the first time this gets called, run the actual string formatting. self.string.get_or_insert_with(|| { let mut s = String::new(); - let mut fmt = fmt::Formatter::new(&mut s); + let mut fmt = fmt::Formatter::new(&mut s, fmt::FormattingOptions::new()); let _err = fmt::Display::fmt(&inner, &mut fmt); s }) diff --git a/std/src/path.rs b/std/src/path.rs index b0291e3aa196f..7fd08a97f1f20 100644 --- a/std/src/path.rs +++ b/std/src/path.rs @@ -298,7 +298,7 @@ where } // Detect scheme on Redox -fn has_redox_scheme(s: &[u8]) -> bool { +pub(crate) fn has_redox_scheme(s: &[u8]) -> bool { cfg!(target_os = "redox") && s.contains(&b':') } @@ -1158,6 +1158,7 @@ impl FusedIterator for Ancestors<'_> {} /// Note that `PathBuf` does not always sanitize arguments, for example /// [`push`] allows paths built from strings which include separators: /// +/// ``` /// use std::path::PathBuf; /// /// let mut path = PathBuf::new(); @@ -1166,6 +1167,7 @@ impl FusedIterator for Ancestors<'_> {} /// path.push("windows"); /// path.push(r"..\otherdir"); /// path.push("system32"); +/// ``` /// /// The behavior of `PathBuf` may be changed to a panic on such inputs /// in the future. [`Extend::extend`] should be used to add multi-part paths. @@ -1762,7 +1764,7 @@ impl From<&Path> for Box { } } -#[stable(feature = "box_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "box_from_mut_slice", since = "1.84.0")] impl From<&mut Path> for Box { /// Creates a boxed [`Path`] from a reference. /// @@ -2000,7 +2002,7 @@ impl From<&Path> for Arc { } } -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut Path> for Arc { /// Converts a [`Path`] into an [`Arc`] by copying the [`Path`] data into a new [`Arc`] buffer. #[inline] @@ -2030,7 +2032,7 @@ impl From<&Path> for Rc { } } -#[stable(feature = "shared_from_mut_slice", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "shared_from_mut_slice", since = "1.84.0")] impl From<&mut Path> for Rc { /// Converts a [`Path`] into an [`Rc`] by copying the [`Path`] data into a new [`Rc`] buffer. #[inline] @@ -2153,7 +2155,7 @@ impl Path { unsafe { Path::new(OsStr::from_encoded_bytes_unchecked(s)) } } // The following (private!) function reveals the byte encoding used for OsStr. - fn as_u8_slice(&self) -> &[u8] { + pub(crate) fn as_u8_slice(&self) -> &[u8] { self.inner.as_encoded_bytes() } @@ -2321,12 +2323,7 @@ impl Path { #[must_use] #[allow(deprecated)] pub fn is_absolute(&self) -> bool { - if cfg!(target_os = "redox") { - // FIXME: Allow Redox prefixes - self.has_root() || has_redox_scheme(self.as_u8_slice()) - } else { - self.has_root() && (cfg!(any(unix, target_os = "wasi")) || self.prefix().is_some()) - } + sys::path::is_absolute(self) } /// Returns `true` if the `Path` is relative, i.e., not absolute. @@ -2349,7 +2346,7 @@ impl Path { !self.is_absolute() } - fn prefix(&self) -> Option> { + pub(crate) fn prefix(&self) -> Option> { self.components().prefix } @@ -2504,6 +2501,7 @@ impl Path { /// assert_eq!(path.strip_prefix("/test/haha/foo.txt/"), Ok(Path::new(""))); /// /// assert!(path.strip_prefix("test").is_err()); + /// assert!(path.strip_prefix("/te").is_err()); /// assert!(path.strip_prefix("/haha").is_err()); /// /// let prefix = PathBuf::from("/test/"); @@ -3580,7 +3578,7 @@ impl Error for StripPrefixError { pub fn absolute>(path: P) -> io::Result { let path = path.as_ref(); if path.as_os_str().is_empty() { - Err(io::const_io_error!(io::ErrorKind::InvalidInput, "cannot make an empty path absolute",)) + Err(io::const_error!(io::ErrorKind::InvalidInput, "cannot make an empty path absolute",)) } else { sys::path::absolute(path) } diff --git a/std/src/path/tests.rs b/std/src/path/tests.rs index ff3f7151bb834..3f96ac4672aff 100644 --- a/std/src/path/tests.rs +++ b/std/src/path/tests.rs @@ -2069,9 +2069,7 @@ fn clone_to_uninit() { let mut storage = vec![MaybeUninit::::uninit(); size_of_val::(a)]; unsafe { a.clone_to_uninit(ptr::from_mut::<[_]>(storage.as_mut_slice()).cast()) }; - assert_eq!(a.as_os_str().as_encoded_bytes(), unsafe { - MaybeUninit::slice_assume_init_ref(&storage) - }); + assert_eq!(a.as_os_str().as_encoded_bytes(), unsafe { storage.assume_init_ref() }); let mut b: Box = Path::new("world.exe").into(); assert_eq!(size_of_val::(a), size_of_val::(&b)); diff --git a/std/src/pipe.rs b/std/src/pipe.rs index 891032e94a669..913c22588a76c 100644 --- a/std/src/pipe.rs +++ b/std/src/pipe.rs @@ -1,20 +1,66 @@ -//! Module for anonymous pipe +//! A cross-platform anonymous pipe. //! -//! ``` -//! #![feature(anonymous_pipe)] +//! This module provides support for anonymous OS pipes, like [pipe] on Linux or [CreatePipe] on +//! Windows. +//! +//! # Behavior +//! +//! A pipe is a synchronous, unidirectional data channel between two or more processes, like an +//! interprocess [`mpsc`](crate::sync::mpsc) provided by the OS. In particular: +//! +//! * A read on a [`PipeReader`] blocks until the pipe is non-empty. +//! * A write on a [`PipeWriter`] blocks when the pipe is full. +//! * When all copies of a [`PipeWriter`] are closed, a read on the corresponding [`PipeReader`] +//! returns EOF. +//! * [`PipeReader`] can be shared, but only one process will consume the data in the pipe. +//! +//! # Capacity +//! +//! Pipe capacity is platform dependent. To quote the Linux [man page]: +//! +//! > Different implementations have different limits for the pipe capacity. Applications should +//! > not rely on a particular capacity: an application should be designed so that a reading process +//! > consumes data as soon as it is available, so that a writing process does not remain blocked. //! +//! # Examples +//! +//! ```no_run +//! #![feature(anonymous_pipe)] //! # #[cfg(miri)] fn main() {} //! # #[cfg(not(miri))] //! # fn main() -> std::io::Result<()> { -//! let (reader, writer) = std::pipe::pipe()?; +//! # use std::process::Command; +//! # use std::io::{Read, Write}; +//! let (ping_rx, mut ping_tx) = std::pipe::pipe()?; +//! let (mut pong_rx, pong_tx) = std::pipe::pipe()?; +//! +//! // Spawn a process that echoes its input. +//! let mut echo_server = Command::new("cat").stdin(ping_rx).stdout(pong_tx).spawn()?; +//! +//! ping_tx.write_all(b"hello")?; +//! // Close to unblock echo_server's reader. +//! drop(ping_tx); +//! +//! let mut buf = String::new(); +//! // Block until echo_server's writer is closed. +//! pong_rx.read_to_string(&mut buf)?; +//! assert_eq!(&buf, "hello"); +//! +//! echo_server.wait()?; //! # Ok(()) //! # } //! ``` - +//! [pipe]: https://man7.org/linux/man-pages/man2/pipe.2.html +//! [CreatePipe]: https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-createpipe +//! [man page]: https://man7.org/linux/man-pages/man7/pipe.7.html use crate::io; use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner}; /// Create anonymous pipe that is close-on-exec and blocking. +/// +/// # Examples +/// +/// See the [module-level](crate::pipe) documentation for examples. #[unstable(feature = "anonymous_pipe", issue = "127154")] #[inline] pub fn pipe() -> io::Result<(PipeReader, PipeWriter)> { @@ -33,6 +79,58 @@ pub struct PipeWriter(pub(crate) AnonPipe); impl PipeReader { /// Create a new [`PipeReader`] instance that shares the same underlying file description. + /// + /// # Examples + /// + /// ```no_run + /// #![feature(anonymous_pipe)] + /// # #[cfg(miri)] fn main() {} + /// # #[cfg(not(miri))] + /// # fn main() -> std::io::Result<()> { + /// # use std::fs; + /// # use std::io::Write; + /// # use std::process::Command; + /// const NUM_SLOT: u8 = 2; + /// const NUM_PROC: u8 = 5; + /// const OUTPUT: &str = "work.txt"; + /// + /// let mut jobs = vec![]; + /// let (reader, mut writer) = std::pipe::pipe()?; + /// + /// // Write NUM_SLOT characters the pipe. + /// writer.write_all(&[b'|'; NUM_SLOT as usize])?; + /// + /// // Spawn several processes that read a character from the pipe, do some work, then + /// // write back to the pipe. When the pipe is empty, the processes block, so only + /// // NUM_SLOT processes can be working at any given time. + /// for _ in 0..NUM_PROC { + /// jobs.push( + /// Command::new("bash") + /// .args(["-c", + /// &format!( + /// "read -n 1\n\ + /// echo -n 'x' >> '{OUTPUT}'\n\ + /// echo -n '|'", + /// ), + /// ]) + /// .stdin(reader.try_clone()?) + /// .stdout(writer.try_clone()?) + /// .spawn()?, + /// ); + /// } + /// + /// // Wait for all jobs to finish. + /// for mut job in jobs { + /// job.wait()?; + /// } + /// + /// // Check our work and clean up. + /// let xs = fs::read_to_string(OUTPUT)?; + /// fs::remove_file(OUTPUT)?; + /// assert_eq!(xs, "x".repeat(NUM_PROC.into())); + /// # Ok(()) + /// # } + /// ``` #[unstable(feature = "anonymous_pipe", issue = "127154")] pub fn try_clone(&self) -> io::Result { self.0.try_clone().map(Self) @@ -41,6 +139,38 @@ impl PipeReader { impl PipeWriter { /// Create a new [`PipeWriter`] instance that shares the same underlying file description. + /// + /// # Examples + /// + /// ```no_run + /// #![feature(anonymous_pipe)] + /// # #[cfg(miri)] fn main() {} + /// # #[cfg(not(miri))] + /// # fn main() -> std::io::Result<()> { + /// # use std::process::Command; + /// # use std::io::Read; + /// let (mut reader, writer) = std::pipe::pipe()?; + /// + /// // Spawn a process that writes to stdout and stderr. + /// let mut peer = Command::new("bash") + /// .args([ + /// "-c", + /// "echo -n foo\n\ + /// echo -n bar >&2" + /// ]) + /// .stdout(writer.try_clone()?) + /// .stderr(writer) + /// .spawn()?; + /// + /// // Read and check the result. + /// let mut msg = String::new(); + /// reader.read_to_string(&mut msg)?; + /// assert_eq!(&msg, "foobar"); + /// + /// peer.wait()?; + /// # Ok(()) + /// # } + /// ``` #[unstable(feature = "anonymous_pipe", issue = "127154")] pub fn try_clone(&self) -> io::Result { self.0.try_clone().map(Self) diff --git a/std/src/prelude/common.rs b/std/src/prelude/common.rs index e4731280ffe35..0f2d8334fca79 100644 --- a/std/src/prelude/common.rs +++ b/std/src/prelude/common.rs @@ -12,7 +12,7 @@ pub use crate::marker::{Send, Sized, Sync, Unpin}; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] pub use crate::ops::{Drop, Fn, FnMut, FnOnce}; -#[unstable(feature = "async_closure", issue = "62290")] +#[stable(feature = "async_closure", since = "1.85.0")] #[doc(no_inline)] pub use crate::ops::{AsyncFn, AsyncFnMut, AsyncFnOnce}; diff --git a/std/src/prelude/mod.rs b/std/src/prelude/mod.rs index 0c610ba67e65c..4ec328208f015 100644 --- a/std/src/prelude/mod.rs +++ b/std/src/prelude/mod.rs @@ -25,6 +25,7 @@ //! //! # Prelude contents //! +//! The items included in the prelude depend on the edition of the crate. //! The first version of the prelude is used in Rust 2015 and Rust 2018, //! and lives in [`std::prelude::v1`]. //! [`std::prelude::rust_2015`] and [`std::prelude::rust_2018`] re-export this prelude. @@ -32,8 +33,9 @@ //! //! * [std::marker]::{[Copy], [Send], [Sized], [Sync], [Unpin]}, //! marker traits that indicate fundamental properties of types. -//! * [std::ops]::{[Drop], [Fn], [FnMut], [FnOnce]}, various -//! operations for both destructors and overloading `()`. +//! * [std::ops]::{[Fn], [FnMut], [FnOnce]}, and their analogous +//! async traits, [std::ops]::{[AsyncFn], [AsyncFnMut], [AsyncFnOnce]}. +//! * [std::ops]::[Drop], for implementing destructors. //! * [std::mem]::[drop], a convenience function for explicitly //! dropping a value. //! * [std::mem]::{[size_of], [size_of_val]}, to get the size of @@ -67,15 +69,21 @@ //! The prelude used in Rust 2021, [`std::prelude::rust_2021`], includes all of the above, //! and in addition re-exports: //! -//! * [std::convert]::{[TryFrom], [TryInto]}, +//! * [std::convert]::{[TryFrom], [TryInto]}. //! * [std::iter]::[FromIterator]. //! +//! The prelude used in Rust 2024, [`std::prelude::rust_2024`], includes all of the above, +//! and in addition re-exports: +//! +//! * [std::future]::{[Future], [IntoFuture]}. +//! //! [std::borrow]: crate::borrow //! [std::boxed]: crate::boxed //! [std::clone]: crate::clone //! [std::cmp]: crate::cmp //! [std::convert]: crate::convert //! [std::default]: crate::default +//! [std::future]: crate::future //! [std::iter]: crate::iter //! [std::marker]: crate::marker //! [std::mem]: crate::mem @@ -85,6 +93,7 @@ //! [`std::prelude::rust_2015`]: rust_2015 //! [`std::prelude::rust_2018`]: rust_2018 //! [`std::prelude::rust_2021`]: rust_2021 +//! [`std::prelude::rust_2024`]: rust_2024 //! [std::result]: crate::result //! [std::slice]: crate::slice //! [std::string]: crate::string @@ -94,6 +103,8 @@ //! [book-dtor]: ../../book/ch15-03-drop.html //! [book-enums]: ../../book/ch06-01-defining-an-enum.html //! [book-iter]: ../../book/ch13-02-iterators.html +//! [Future]: crate::future::Future +//! [IntoFuture]: crate::future::IntoFuture // No formatting: this file is nothing but re-exports, and their order is worth preserving. #![cfg_attr(rustfmt, rustfmt::skip)] @@ -158,12 +169,12 @@ pub mod rust_2021 { /// The 2024 version of the prelude of The Rust Standard Library. /// /// See the [module-level documentation](self) for more. -#[unstable(feature = "prelude_2024", issue = "121042")] +#[stable(feature = "prelude_2024", since = "1.85.0")] pub mod rust_2024 { #[stable(feature = "rust1", since = "1.0.0")] pub use super::common::*; - #[unstable(feature = "prelude_2024", issue = "121042")] + #[stable(feature = "prelude_2024", since = "1.85.0")] #[doc(no_inline)] pub use core::prelude::rust_2024::*; } diff --git a/std/src/process.rs b/std/src/process.rs index 6933528cdbd0a..e0dd2e14817a8 100644 --- a/std/src/process.rs +++ b/std/src/process.rs @@ -224,7 +224,7 @@ pub struct Child { /// has been captured. You might find it helpful to do /// /// ```ignore (incomplete) - /// let stdin = child.stdin.take().unwrap(); + /// let stdin = child.stdin.take().expect("handle present"); /// ``` /// /// to avoid partially moving the `child` and thus blocking yourself from calling @@ -236,7 +236,7 @@ pub struct Child { /// has been captured. You might find it helpful to do /// /// ```ignore (incomplete) - /// let stdout = child.stdout.take().unwrap(); + /// let stdout = child.stdout.take().expect("handle present"); /// ``` /// /// to avoid partially moving the `child` and thus blocking yourself from calling @@ -248,7 +248,7 @@ pub struct Child { /// has been captured. You might find it helpful to do /// /// ```ignore (incomplete) - /// let stderr = child.stderr.take().unwrap(); + /// let stderr = child.stderr.take().expect("handle present"); /// ``` /// /// to avoid partially moving the `child` and thus blocking yourself from calling @@ -868,13 +868,17 @@ impl Command { /// /// # Examples /// + /// Prevent any inherited `GIT_DIR` variable from changing the target of the `git` command, + /// while allowing all other variables, like `GIT_AUTHOR_NAME`. + /// /// ```no_run /// use std::process::Command; /// - /// Command::new("ls") - /// .env_remove("PATH") - /// .spawn() - /// .expect("ls command failed to start"); + /// Command::new("git") + /// .arg("commit") + /// .env_remove("GIT_DIR") + /// .spawn()?; + /// # std::io::Result::Ok(()) /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn env_remove>(&mut self, key: K) -> &mut Command { @@ -896,13 +900,17 @@ impl Command { /// /// # Examples /// + /// The behavior of `sort` is affected by `LANG` and `LC_*` environment variables. + /// Clearing the environment makes `sort`'s behavior independent of the parent processes' language. + /// /// ```no_run /// use std::process::Command; /// - /// Command::new("ls") + /// Command::new("sort") + /// .arg("file.txt") /// .env_clear() - /// .spawn() - /// .expect("ls command failed to start"); + /// .spawn()?; + /// # std::io::Result::Ok(()) /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn env_clear(&mut self) -> &mut Command { @@ -1052,14 +1060,14 @@ impl Command { /// use std::io::{self, Write}; /// let output = Command::new("/bin/cat") /// .arg("file.txt") - /// .output() - /// .expect("failed to execute process"); + /// .output()?; /// /// println!("status: {}", output.status); - /// io::stdout().write_all(&output.stdout).unwrap(); - /// io::stderr().write_all(&output.stderr).unwrap(); + /// io::stdout().write_all(&output.stdout)?; + /// io::stderr().write_all(&output.stderr)?; /// /// assert!(output.status.success()); + /// # io::Result::Ok(()) /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn output(&mut self) -> io::Result { @@ -1283,13 +1291,13 @@ impl fmt::Debug for Output { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { let stdout_utf8 = str::from_utf8(&self.stdout); let stdout_debug: &dyn fmt::Debug = match stdout_utf8 { - Ok(ref str) => str, + Ok(ref s) => s, Err(_) => &self.stdout, }; let stderr_utf8 = str::from_utf8(&self.stderr); let stderr_debug: &dyn fmt::Debug = match stderr_utf8 { - Ok(ref str) => str, + Ok(ref s) => s, Err(_) => &self.stderr, }; @@ -1391,11 +1399,11 @@ impl Stdio { /// let output = Command::new("rev") /// .stdin(Stdio::inherit()) /// .stdout(Stdio::piped()) - /// .output() - /// .expect("Failed to execute command"); + /// .output()?; /// /// print!("You piped in the reverse of: "); - /// io::stdout().write_all(&output.stdout).unwrap(); + /// io::stdout().write_all(&output.stdout)?; + /// # io::Result::Ok(()) /// ``` #[must_use] #[stable(feature = "process", since = "1.0.0")] @@ -1575,14 +1583,14 @@ impl From for Stdio { /// use std::process::Command; /// /// // With the `foo.txt` file containing "Hello, world!" - /// let file = File::open("foo.txt").unwrap(); + /// let file = File::open("foo.txt")?; /// /// let reverse = Command::new("rev") /// .stdin(file) // Implicit File conversion into a Stdio - /// .output() - /// .expect("failed reverse command"); + /// .output()?; /// /// assert_eq!(reverse.stdout, b"!dlrow ,olleH"); + /// # std::io::Result::Ok(()) /// ``` fn from(file: fs::File) -> Stdio { Stdio::from_inner(file.into_inner().into()) @@ -2179,7 +2187,7 @@ impl Child { /// ```no_run /// use std::process::Command; /// - /// let mut child = Command::new("ls").spawn().unwrap(); + /// let mut child = Command::new("ls").spawn()?; /// /// match child.try_wait() { /// Ok(Some(status)) => println!("exited with: {status}"), @@ -2190,6 +2198,7 @@ impl Child { /// } /// Err(e) => println!("error attempting to wait: {e}"), /// } + /// # std::io::Result::Ok(()) /// ``` #[stable(feature = "process_try_wait", since = "1.18.0")] pub fn try_wait(&mut self) -> io::Result> { diff --git a/std/src/process/tests.rs b/std/src/process/tests.rs index fb0b495961c36..e8cbfe337bccf 100644 --- a/std/src/process/tests.rs +++ b/std/src/process/tests.rs @@ -450,7 +450,7 @@ fn test_creation_flags() { fn test_proc_thread_attributes() { use crate::mem; use crate::os::windows::io::AsRawHandle; - use crate::os::windows::process::CommandExt; + use crate::os::windows::process::{CommandExt, ProcThreadAttributeList}; use crate::sys::c::{BOOL, CloseHandle, HANDLE}; use crate::sys::cvt; @@ -490,12 +490,14 @@ fn test_proc_thread_attributes() { let mut child_cmd = Command::new("cmd"); - unsafe { - child_cmd - .raw_attribute(PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, parent.0.as_raw_handle() as isize); - } + let parent_process_handle = parent.0.as_raw_handle(); + + let mut attribute_list = ProcThreadAttributeList::build() + .attribute(PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &parent_process_handle) + .finish() + .unwrap(); - let child = ProcessDropGuard(child_cmd.spawn().unwrap()); + let child = ProcessDropGuard(child_cmd.spawn_with_attributes(&mut attribute_list).unwrap()); let h_snapshot = unsafe { CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) }; diff --git a/std/src/rt.rs b/std/src/rt.rs index b2492238bd37b..384369b0012b5 100644 --- a/std/src/rt.rs +++ b/std/src/rt.rs @@ -23,7 +23,7 @@ pub use core::panicking::{panic_display, panic_fmt}; #[rustfmt::skip] use crate::any::Any; use crate::sync::Once; -use crate::thread::{self, Thread}; +use crate::thread::{self, main_thread}; use crate::{mem, panic, sys}; // Prints to the "panic output", depending on the platform this may be: @@ -67,7 +67,7 @@ macro_rules! rtunwrap { }; } -fn handle_rt_panic(e: Box) { +fn handle_rt_panic(e: Box) -> T { mem::forget(e); rtabort!("initialization or cleanup bug"); } @@ -102,24 +102,9 @@ unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { sys::init(argc, argv, sigpipe) }; - // Set up the current thread handle to give it the right name. - // - // When code running before main uses `ReentrantLock` (for example by - // using `println!`), the thread ID can become initialized before we - // create this handle. Since `set_current` fails when the ID of the - // handle does not match the current ID, we should attempt to use the - // current thread ID here instead of unconditionally creating a new - // one. Also see #130210. - let thread = unsafe { Thread::new_main(thread::current_id()) }; - if let Err(_thread) = thread::set_current(thread) { - // `thread::current` will create a new handle if none has been set yet. - // Thus, if someone uses it before main, this call will fail. That's a - // bad idea though, as we then cannot set the main thread name here. - // - // FIXME: detect the main thread in `thread::current` and use the - // correct name there. - rtabort!("code running before main must not use thread::current"); - } + // Remember the main thread ID to give it the correct name. + // SAFETY: this is the only time and place where we call this function. + unsafe { main_thread::set(thread::current_id()) }; } /// Clean up the thread-local runtime state. This *should* be run after all other @@ -157,7 +142,7 @@ fn lang_start_internal( argc: isize, argv: *const *const u8, sigpipe: u8, -) -> Result { +) -> isize { // Guard against the code called by this function from unwinding outside of the Rust-controlled // code, which is UB. This is a requirement imposed by a combination of how the // `#[lang="start"]` attribute is implemented as well as by the implementation of the panicking @@ -168,19 +153,33 @@ fn lang_start_internal( // panic is a std implementation bug. A quite likely one too, as there isn't any way to // prevent std from accidentally introducing a panic to these functions. Another is from // user code from `main` or, more nefariously, as described in e.g. issue #86030. - // SAFETY: Only called once during runtime initialization. - panic::catch_unwind(move || unsafe { init(argc, argv, sigpipe) }) - .unwrap_or_else(handle_rt_panic); - let ret_code = panic::catch_unwind(move || panic::catch_unwind(main).unwrap_or(101) as isize) - .map_err(move |e| { - mem::forget(e); - rtabort!("drop of the panic payload panicked"); + // + // We use `catch_unwind` with `handle_rt_panic` instead of `abort_unwind` to make the error in + // case of a panic a bit nicer. + panic::catch_unwind(move || { + // SAFETY: Only called once during runtime initialization. + unsafe { init(argc, argv, sigpipe) }; + + let ret_code = panic::catch_unwind(main).unwrap_or_else(move |payload| { + // Carefully dispose of the panic payload. + let payload = panic::AssertUnwindSafe(payload); + panic::catch_unwind(move || drop({ payload }.0)).unwrap_or_else(move |e| { + mem::forget(e); // do *not* drop the 2nd payload + rtabort!("drop of the panic payload panicked"); + }); + // Return error code for panicking programs. + 101 }); - panic::catch_unwind(cleanup).unwrap_or_else(handle_rt_panic); - // Guard against multiple threads calling `libc::exit` concurrently. - // See the documentation for `unique_thread_exit` for more information. - panic::catch_unwind(crate::sys::exit_guard::unique_thread_exit).unwrap_or_else(handle_rt_panic); - ret_code + let ret_code = ret_code as isize; + + cleanup(); + // Guard against multiple threads calling `libc::exit` concurrently. + // See the documentation for `unique_thread_exit` for more information. + crate::sys::exit_guard::unique_thread_exit(); + + ret_code + }) + .unwrap_or_else(handle_rt_panic) } #[cfg(not(any(test, doctest)))] @@ -191,11 +190,10 @@ fn lang_start( argv: *const *const u8, sigpipe: u8, ) -> isize { - let Ok(v) = lang_start_internal( + lang_start_internal( &move || crate::sys::backtrace::__rust_begin_short_backtrace(main).report().to_i32(), argc, argv, sigpipe, - ); - v + ) } diff --git a/std/src/sync/barrier.rs b/std/src/sync/barrier.rs index 82cc13a74b7f1..862753e4765dc 100644 --- a/std/src/sync/barrier.rs +++ b/std/src/sync/barrier.rs @@ -2,6 +2,7 @@ mod tests; use crate::fmt; +// FIXME(nonpoison_mutex,nonpoison_condvar): switch to nonpoison versions once they are available use crate::sync::{Condvar, Mutex}; /// A barrier enables multiple threads to synchronize the beginning @@ -10,26 +11,22 @@ use crate::sync::{Condvar, Mutex}; /// # Examples /// /// ``` -/// use std::sync::{Arc, Barrier}; +/// use std::sync::Barrier; /// use std::thread; /// /// let n = 10; -/// let mut handles = Vec::with_capacity(n); -/// let barrier = Arc::new(Barrier::new(n)); -/// for _ in 0..n { -/// let c = Arc::clone(&barrier); -/// // The same messages will be printed together. -/// // You will NOT see any interleaving. -/// handles.push(thread::spawn(move || { -/// println!("before wait"); -/// c.wait(); -/// println!("after wait"); -/// })); -/// } -/// // Wait for other threads to finish. -/// for handle in handles { -/// handle.join().unwrap(); -/// } +/// let barrier = Barrier::new(n); +/// thread::scope(|s| { +/// for _ in 0..n { +/// // The same messages will be printed together. +/// // You will NOT see any interleaving. +/// s.spawn(|| { +/// println!("before wait"); +/// barrier.wait(); +/// println!("after wait"); +/// }); +/// } +/// }); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub struct Barrier { @@ -105,26 +102,22 @@ impl Barrier { /// # Examples /// /// ``` - /// use std::sync::{Arc, Barrier}; + /// use std::sync::Barrier; /// use std::thread; /// /// let n = 10; - /// let mut handles = Vec::with_capacity(n); - /// let barrier = Arc::new(Barrier::new(n)); - /// for _ in 0..n { - /// let c = Arc::clone(&barrier); - /// // The same messages will be printed together. - /// // You will NOT see any interleaving. - /// handles.push(thread::spawn(move || { - /// println!("before wait"); - /// c.wait(); - /// println!("after wait"); - /// })); - /// } - /// // Wait for other threads to finish. - /// for handle in handles { - /// handle.join().unwrap(); - /// } + /// let barrier = Barrier::new(n); + /// thread::scope(|s| { + /// for _ in 0..n { + /// // The same messages will be printed together. + /// // You will NOT see any interleaving. + /// s.spawn(|| { + /// println!("before wait"); + /// barrier.wait(); + /// println!("after wait"); + /// }); + /// } + /// }); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn wait(&self) -> BarrierWaitResult { diff --git a/std/src/sync/lazy_lock.rs b/std/src/sync/lazy_lock.rs index 40510f5613450..1e4f9b79e0f4a 100644 --- a/std/src/sync/lazy_lock.rs +++ b/std/src/sync/lazy_lock.rs @@ -1,4 +1,4 @@ -use super::once::ExclusiveState; +use super::poison::once::ExclusiveState; use crate::cell::UnsafeCell; use crate::mem::ManuallyDrop; use crate::ops::Deref; @@ -63,6 +63,7 @@ union Data { /// ``` #[stable(feature = "lazy_cell", since = "1.80.0")] pub struct LazyLock T> { + // FIXME(nonpoison_once): if possible, switch to nonpoison version once it is available once: Once, data: UnsafeCell>, } diff --git a/std/src/sync/mod.rs b/std/src/sync/mod.rs index 0fb77331293fe..5b50a3c6ccf90 100644 --- a/std/src/sync/mod.rs +++ b/std/src/sync/mod.rs @@ -167,6 +167,10 @@ #![stable(feature = "rust1", since = "1.0.0")] +// No formatting: this file is just re-exports, and their order is worth preserving. +#![cfg_attr(rustfmt, rustfmt::skip)] + +// These come from `core` & `alloc` and only in one flavor: no poisoning. #[unstable(feature = "exclusive_wrapper", issue = "98407")] pub use core::sync::Exclusive; #[stable(feature = "rust1", since = "1.0.0")] @@ -175,40 +179,54 @@ pub use core::sync::atomic; #[stable(feature = "rust1", since = "1.0.0")] pub use alloc_crate::sync::{Arc, Weak}; +// FIXME(sync_nonpoison,sync_poison_mod): remove all `#[doc(inline)]` once the modules are stabilized. + +// These exist only in one flavor: no poisoning. #[stable(feature = "rust1", since = "1.0.0")] pub use self::barrier::{Barrier, BarrierWaitResult}; -#[stable(feature = "rust1", since = "1.0.0")] -pub use self::condvar::{Condvar, WaitTimeoutResult}; #[stable(feature = "lazy_cell", since = "1.80.0")] pub use self::lazy_lock::LazyLock; -#[unstable(feature = "mapped_lock_guards", issue = "117108")] -pub use self::mutex::MappedMutexGuard; -#[stable(feature = "rust1", since = "1.0.0")] -pub use self::mutex::{Mutex, MutexGuard}; -#[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated)] -pub use self::once::{ONCE_INIT, Once, OnceState}; #[stable(feature = "once_cell", since = "1.70.0")] pub use self::once_lock::OnceLock; -#[stable(feature = "rust1", since = "1.0.0")] -pub use self::poison::{LockResult, PoisonError, TryLockError, TryLockResult}; #[unstable(feature = "reentrant_lock", issue = "121440")] pub use self::reentrant_lock::{ReentrantLock, ReentrantLockGuard}; -#[unstable(feature = "mapped_lock_guards", issue = "117108")] -pub use self::rwlock::{MappedRwLockReadGuard, MappedRwLockWriteGuard}; + +// These make sense and exist only with poisoning. #[stable(feature = "rust1", since = "1.0.0")] -pub use self::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}; +#[doc(inline)] +pub use self::poison::{LockResult, PoisonError}; + +// These (should) exist in both flavors: with and without poisoning. +// FIXME(sync_nonpoison): implement nonpoison versions: +// * Mutex (nonpoison_mutex) +// * Condvar (nonpoison_condvar) +// * Once (nonpoison_once) +// * RwLock (nonpoison_rwlock) +// The historical default is the version with poisoning. +#[stable(feature = "rust1", since = "1.0.0")] +#[doc(inline)] +pub use self::poison::{ + Mutex, MutexGuard, TryLockError, TryLockResult, + Condvar, WaitTimeoutResult, + Once, OnceState, + RwLock, RwLockReadGuard, RwLockWriteGuard, +}; +#[stable(feature = "rust1", since = "1.0.0")] +#[doc(inline)] +#[expect(deprecated)] +pub use self::poison::ONCE_INIT; +#[unstable(feature = "mapped_lock_guards", issue = "117108")] +#[doc(inline)] +pub use self::poison::{MappedMutexGuard, MappedRwLockReadGuard, MappedRwLockWriteGuard}; #[unstable(feature = "mpmc_channel", issue = "126840")] pub mod mpmc; pub mod mpsc; +#[unstable(feature = "sync_poison_mod", issue = "134646")] +pub mod poison; + mod barrier; -mod condvar; mod lazy_lock; -mod mutex; -pub(crate) mod once; mod once_lock; -mod poison; mod reentrant_lock; -mod rwlock; diff --git a/std/src/sync/once_lock.rs b/std/src/sync/once_lock.rs index 0ae3cf4df3614..49f2dafd8fd9c 100644 --- a/std/src/sync/once_lock.rs +++ b/std/src/sync/once_lock.rs @@ -101,6 +101,7 @@ use crate::sync::Once; /// ``` #[stable(feature = "once_cell", since = "1.70.0")] pub struct OnceLock { + // FIXME(nonpoison_once): switch to nonpoison version once it is available once: Once, // Whether or not the value is initialized is tracked by `once.is_completed()`. value: UnsafeCell>, diff --git a/std/src/sync/poison.rs b/std/src/sync/poison.rs index da66a088e51b1..1b8809734b8a8 100644 --- a/std/src/sync/poison.rs +++ b/std/src/sync/poison.rs @@ -1,3 +1,78 @@ +//! Synchronization objects that employ poisoning. +//! +//! # Poisoning +//! +//! All synchronization objects in this module implement a strategy called "poisoning" +//! where if a thread panics while holding the exclusive access granted by the primitive, +//! the state of the primitive is set to "poisoned". +//! This information is then propagated to all other threads +//! to signify that the data protected by this primitive is likely tainted +//! (some invariant is not being upheld). +//! +//! The specifics of how this "poisoned" state affects other threads +//! depend on the primitive. See [#Overview] bellow. +//! +//! For the alternative implementations that do not employ poisoning, +//! see `std::sys::nonpoisoning`. +//! +//! # Overview +//! +//! Below is a list of synchronization objects provided by this module +//! with a high-level overview for each object and a description +//! of how it employs "poisoning". +//! +//! - [`Condvar`]: Condition Variable, providing the ability to block +//! a thread while waiting for an event to occur. +//! +//! Condition variables are typically associated with +//! a boolean predicate (a condition) and a mutex. +//! This implementation is associated with [`poison::Mutex`](Mutex), +//! which employs poisoning. +//! For this reason, [`Condvar::wait()`] will return a [`LockResult`], +//! just like [`poison::Mutex::lock()`](Mutex::lock) does. +//! +//! - [`Mutex`]: Mutual Exclusion mechanism, which ensures that at +//! most one thread at a time is able to access some data. +//! +//! [`Mutex::lock()`] returns a [`LockResult`], +//! providing a way to deal with the poisoned state. +//! See [`Mutex`'s documentation](Mutex#poisoning) for more. +//! +//! - [`Once`]: A thread-safe way to run a piece of code only once. +//! Mostly useful for implementing one-time global initialization. +//! +//! [`Once`] is poisoned if the piece of code passed to +//! [`Once::call_once()`] or [`Once::call_once_force()`] panics. +//! When in poisoned state, subsequent calls to [`Once::call_once()`] will panic too. +//! [`Once::call_once_force()`] can be used to clear the poisoned state. +//! +//! - [`RwLock`]: Provides a mutual exclusion mechanism which allows +//! multiple readers at the same time, while allowing only one +//! writer at a time. In some cases, this can be more efficient than +//! a mutex. +//! +//! This implementation, like [`Mutex`], will become poisoned on a panic. +//! Note, however, that an `RwLock` may only be poisoned if a panic occurs +//! while it is locked exclusively (write mode). If a panic occurs in any reader, +//! then the lock will not be poisoned. + +// FIXME(sync_nonpoison) add links to sync::nonpoison to the doc comment above. + +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::condvar::{Condvar, WaitTimeoutResult}; +#[unstable(feature = "mapped_lock_guards", issue = "117108")] +pub use self::mutex::MappedMutexGuard; +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::mutex::{Mutex, MutexGuard}; +#[stable(feature = "rust1", since = "1.0.0")] +#[expect(deprecated)] +pub use self::once::ONCE_INIT; +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::once::{Once, OnceState}; +#[unstable(feature = "mapped_lock_guards", issue = "117108")] +pub use self::rwlock::{MappedRwLockReadGuard, MappedRwLockWriteGuard}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}; use crate::error::Error; use crate::fmt; #[cfg(panic = "unwind")] @@ -5,7 +80,13 @@ use crate::sync::atomic::{AtomicBool, Ordering}; #[cfg(panic = "unwind")] use crate::thread; -pub struct Flag { +mod condvar; +#[stable(feature = "rust1", since = "1.0.0")] +mod mutex; +pub(crate) mod once; +mod rwlock; + +pub(crate) struct Flag { #[cfg(panic = "unwind")] failed: AtomicBool, } @@ -78,7 +159,7 @@ impl Flag { } #[derive(Clone)] -pub struct Guard { +pub(crate) struct Guard { #[cfg(panic = "unwind")] panicking: bool, } @@ -87,8 +168,8 @@ pub struct Guard { /// /// Both [`Mutex`]es and [`RwLock`]s are poisoned whenever a thread fails while the lock /// is held. The precise semantics for when a lock is poisoned is documented on -/// each lock, but once a lock is poisoned then all future acquisitions will -/// return this error. +/// each lock. For a lock in the poisoned state, unless the state is cleared manually, +/// all future acquisitions will return this error. /// /// # Examples /// @@ -118,7 +199,7 @@ pub struct Guard { /// [`RwLock`]: crate::sync::RwLock #[stable(feature = "rust1", since = "1.0.0")] pub struct PoisonError { - guard: T, + data: T, #[cfg(not(panic = "unwind"))] _never: !, } @@ -147,14 +228,15 @@ pub enum TryLockError { /// A type alias for the result of a lock method which can be poisoned. /// /// The [`Ok`] variant of this result indicates that the primitive was not -/// poisoned, and the `Guard` is contained within. The [`Err`] variant indicates +/// poisoned, and the operation result is contained within. The [`Err`] variant indicates /// that the primitive was poisoned. Note that the [`Err`] variant *also* carries -/// the associated guard, and it can be acquired through the [`into_inner`] -/// method. +/// an associated value assigned by the lock method, and it can be acquired through the +/// [`into_inner`] method. The semantics of the associated value depends on the corresponding +/// lock method. /// /// [`into_inner`]: PoisonError::into_inner #[stable(feature = "rust1", since = "1.0.0")] -pub type LockResult = Result>; +pub type LockResult = Result>; /// A type alias for the result of a nonblocking locking method. /// @@ -195,8 +277,8 @@ impl PoisonError { /// This method may panic if std was built with `panic="abort"`. #[cfg(panic = "unwind")] #[stable(feature = "sync_poison", since = "1.2.0")] - pub fn new(guard: T) -> PoisonError { - PoisonError { guard } + pub fn new(data: T) -> PoisonError { + PoisonError { data } } /// Creates a `PoisonError`. @@ -208,12 +290,12 @@ impl PoisonError { #[cfg(not(panic = "unwind"))] #[stable(feature = "sync_poison", since = "1.2.0")] #[track_caller] - pub fn new(_guard: T) -> PoisonError { + pub fn new(_data: T) -> PoisonError { panic!("PoisonError created in a libstd built with panic=\"abort\"") } /// Consumes this error indicating that a lock is poisoned, returning the - /// underlying guard to allow access regardless. + /// associated data. /// /// # Examples /// @@ -238,21 +320,21 @@ impl PoisonError { /// ``` #[stable(feature = "sync_poison", since = "1.2.0")] pub fn into_inner(self) -> T { - self.guard + self.data } /// Reaches into this error indicating that a lock is poisoned, returning a - /// reference to the underlying guard to allow access regardless. + /// reference to the associated data. #[stable(feature = "sync_poison", since = "1.2.0")] pub fn get_ref(&self) -> &T { - &self.guard + &self.data } /// Reaches into this error indicating that a lock is poisoned, returning a - /// mutable reference to the underlying guard to allow access regardless. + /// mutable reference to the associated data. #[stable(feature = "sync_poison", since = "1.2.0")] pub fn get_mut(&mut self) -> &mut T { - &mut self.guard + &mut self.data } } @@ -315,13 +397,13 @@ impl Error for TryLockError { } } -pub fn map_result(result: LockResult, f: F) -> LockResult +pub(crate) fn map_result(result: LockResult, f: F) -> LockResult where F: FnOnce(T) -> U, { match result { Ok(t) => Ok(f(t)), #[cfg(panic = "unwind")] - Err(PoisonError { guard }) => Err(PoisonError::new(f(guard))), + Err(PoisonError { data }) => Err(PoisonError::new(f(data))), } } diff --git a/std/src/sync/condvar.rs b/std/src/sync/poison/condvar.rs similarity index 99% rename from std/src/sync/condvar.rs rename to std/src/sync/poison/condvar.rs index 44ffcb528d937..a6e2389c93baf 100644 --- a/std/src/sync/condvar.rs +++ b/std/src/sync/poison/condvar.rs @@ -2,7 +2,7 @@ mod tests; use crate::fmt; -use crate::sync::{LockResult, MutexGuard, PoisonError, mutex, poison}; +use crate::sync::poison::{self, LockResult, MutexGuard, PoisonError, mutex}; use crate::sys::sync as sys; use crate::time::{Duration, Instant}; @@ -16,6 +16,8 @@ use crate::time::{Duration, Instant}; #[stable(feature = "wait_timeout", since = "1.5.0")] pub struct WaitTimeoutResult(bool); +// FIXME(sync_nonpoison): `WaitTimeoutResult` is actually poisoning-agnostic, it seems. +// Should we take advantage of this fact? impl WaitTimeoutResult { /// Returns `true` if the wait was known to have timed out. /// diff --git a/std/src/sync/condvar/tests.rs b/std/src/sync/poison/condvar/tests.rs similarity index 100% rename from std/src/sync/condvar/tests.rs rename to std/src/sync/poison/condvar/tests.rs diff --git a/std/src/sync/mutex.rs b/std/src/sync/poison/mutex.rs similarity index 89% rename from std/src/sync/mutex.rs rename to std/src/sync/poison/mutex.rs index fe2aca031a248..01ef71a187fec 100644 --- a/std/src/sync/mutex.rs +++ b/std/src/sync/poison/mutex.rs @@ -4,10 +4,10 @@ mod tests; use crate::cell::UnsafeCell; use crate::fmt; use crate::marker::PhantomData; -use crate::mem::ManuallyDrop; +use crate::mem::{self, ManuallyDrop}; use crate::ops::{Deref, DerefMut}; use crate::ptr::NonNull; -use crate::sync::{LockResult, TryLockError, TryLockResult, poison}; +use crate::sync::{LockResult, PoisonError, TryLockError, TryLockResult, poison}; use crate::sys::sync as sys; /// A mutual exclusion primitive useful for protecting shared data @@ -273,6 +273,100 @@ impl Mutex { pub const fn new(t: T) -> Mutex { Mutex { inner: sys::Mutex::new(), poison: poison::Flag::new(), data: UnsafeCell::new(t) } } + + /// Returns the contained value by cloning it. + /// + /// # Errors + /// + /// If another user of this mutex panicked while holding the mutex, then + /// this call will return an error instead. + /// + /// # Examples + /// + /// ``` + /// #![feature(lock_value_accessors)] + /// + /// use std::sync::Mutex; + /// + /// let mut mutex = Mutex::new(7); + /// + /// assert_eq!(mutex.get_cloned().unwrap(), 7); + /// ``` + #[unstable(feature = "lock_value_accessors", issue = "133407")] + pub fn get_cloned(&self) -> Result> + where + T: Clone, + { + match self.lock() { + Ok(guard) => Ok((*guard).clone()), + Err(_) => Err(PoisonError::new(())), + } + } + + /// Sets the contained value. + /// + /// # Errors + /// + /// If another user of this mutex panicked while holding the mutex, then + /// this call will return an error containing the provided `value` instead. + /// + /// # Examples + /// + /// ``` + /// #![feature(lock_value_accessors)] + /// + /// use std::sync::Mutex; + /// + /// let mut mutex = Mutex::new(7); + /// + /// assert_eq!(mutex.get_cloned().unwrap(), 7); + /// mutex.set(11).unwrap(); + /// assert_eq!(mutex.get_cloned().unwrap(), 11); + /// ``` + #[unstable(feature = "lock_value_accessors", issue = "133407")] + pub fn set(&self, value: T) -> Result<(), PoisonError> { + if mem::needs_drop::() { + // If the contained value has non-trivial destructor, we + // call that destructor after the lock being released. + self.replace(value).map(drop) + } else { + match self.lock() { + Ok(mut guard) => { + *guard = value; + + Ok(()) + } + Err(_) => Err(PoisonError::new(value)), + } + } + } + + /// Replaces the contained value with `value`, and returns the old contained value. + /// + /// # Errors + /// + /// If another user of this mutex panicked while holding the mutex, then + /// this call will return an error containing the provided `value` instead. + /// + /// # Examples + /// + /// ``` + /// #![feature(lock_value_accessors)] + /// + /// use std::sync::Mutex; + /// + /// let mut mutex = Mutex::new(7); + /// + /// assert_eq!(mutex.replace(11).unwrap(), 7); + /// assert_eq!(mutex.get_cloned().unwrap(), 11); + /// ``` + #[unstable(feature = "lock_value_accessors", issue = "133407")] + pub fn replace(&self, value: T) -> LockResult { + match self.lock() { + Ok(mut guard) => Ok(mem::replace(&mut *guard, value)), + Err(_) => Err(PoisonError::new(value)), + } + } } impl Mutex { @@ -290,7 +384,8 @@ impl Mutex { /// # Errors /// /// If another user of this mutex panicked while holding the mutex, then - /// this call will return an error once the mutex is acquired. + /// this call will return an error once the mutex is acquired. The acquired + /// mutex guard will be contained in the returned error. /// /// # Panics /// @@ -331,7 +426,8 @@ impl Mutex { /// /// If another user of this mutex panicked while holding the mutex, then /// this call will return the [`Poisoned`] error if the mutex would - /// otherwise be acquired. + /// otherwise be acquired. An acquired lock guard will be contained + /// in the returned error. /// /// If the mutex could not be acquired because it is already locked, then /// this call will return the [`WouldBlock`] error. @@ -438,7 +534,8 @@ impl Mutex { /// # Errors /// /// If another user of this mutex panicked while holding the mutex, then - /// this call will return an error instead. + /// this call will return an error containing the underlying data + /// instead. /// /// # Examples /// @@ -465,7 +562,8 @@ impl Mutex { /// # Errors /// /// If another user of this mutex panicked while holding the mutex, then - /// this call will return an error instead. + /// this call will return an error containing a mutable reference to the + /// underlying data instead. /// /// # Examples /// diff --git a/std/src/sync/mutex/tests.rs b/std/src/sync/poison/mutex/tests.rs similarity index 69% rename from std/src/sync/mutex/tests.rs rename to std/src/sync/poison/mutex/tests.rs index 19ec096c59334..395c8aada089a 100644 --- a/std/src/sync/mutex/tests.rs +++ b/std/src/sync/poison/mutex/tests.rs @@ -1,13 +1,34 @@ +use crate::fmt::Debug; +use crate::ops::FnMut; +use crate::panic::{self, AssertUnwindSafe}; use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::sync::mpsc::channel; use crate::sync::{Arc, Condvar, MappedMutexGuard, Mutex, MutexGuard, TryLockError}; -use crate::thread; +use crate::{hint, mem, thread}; struct Packet(Arc<(Mutex, Condvar)>); #[derive(Eq, PartialEq, Debug)] struct NonCopy(i32); +#[derive(Eq, PartialEq, Debug)] +struct NonCopyNeedsDrop(i32); + +impl Drop for NonCopyNeedsDrop { + fn drop(&mut self) { + hint::black_box(()); + } +} + +#[test] +fn test_needs_drop() { + assert!(!mem::needs_drop::()); + assert!(mem::needs_drop::()); +} + +#[derive(Clone, Eq, PartialEq, Debug)] +struct Cloneable(i32); + #[test] fn smoke() { let m = Mutex::new(()); @@ -57,6 +78,21 @@ fn try_lock() { *m.try_lock().unwrap() = (); } +fn new_poisoned_mutex(value: T) -> Mutex { + let mutex = Mutex::new(value); + + let catch_unwind_result = panic::catch_unwind(AssertUnwindSafe(|| { + let _guard = mutex.lock().unwrap(); + + panic!("test panic to poison mutex"); + })); + + assert!(catch_unwind_result.is_err()); + assert!(mutex.is_poisoned()); + + mutex +} + #[test] fn test_into_inner() { let m = Mutex::new(NonCopy(10)); @@ -83,21 +119,31 @@ fn test_into_inner_drop() { #[test] fn test_into_inner_poison() { - let m = Arc::new(Mutex::new(NonCopy(10))); - let m2 = m.clone(); - let _ = thread::spawn(move || { - let _lock = m2.lock().unwrap(); - panic!("test panic in inner thread to poison mutex"); - }) - .join(); + let m = new_poisoned_mutex(NonCopy(10)); - assert!(m.is_poisoned()); - match Arc::try_unwrap(m).unwrap().into_inner() { + match m.into_inner() { Err(e) => assert_eq!(e.into_inner(), NonCopy(10)), Ok(x) => panic!("into_inner of poisoned Mutex is Ok: {x:?}"), } } +#[test] +fn test_get_cloned() { + let m = Mutex::new(Cloneable(10)); + + assert_eq!(m.get_cloned().unwrap(), Cloneable(10)); +} + +#[test] +fn test_get_cloned_poison() { + let m = new_poisoned_mutex(Cloneable(10)); + + match m.get_cloned() { + Err(e) => assert_eq!(e.into_inner(), ()), + Ok(x) => panic!("get of poisoned Mutex is Ok: {x:?}"), + } +} + #[test] fn test_get_mut() { let mut m = Mutex::new(NonCopy(10)); @@ -107,21 +153,90 @@ fn test_get_mut() { #[test] fn test_get_mut_poison() { - let m = Arc::new(Mutex::new(NonCopy(10))); - let m2 = m.clone(); - let _ = thread::spawn(move || { - let _lock = m2.lock().unwrap(); - panic!("test panic in inner thread to poison mutex"); - }) - .join(); + let mut m = new_poisoned_mutex(NonCopy(10)); - assert!(m.is_poisoned()); - match Arc::try_unwrap(m).unwrap().get_mut() { + match m.get_mut() { Err(e) => assert_eq!(*e.into_inner(), NonCopy(10)), Ok(x) => panic!("get_mut of poisoned Mutex is Ok: {x:?}"), } } +#[test] +fn test_set() { + fn inner(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T) + where + T: Debug + Eq, + { + let m = Mutex::new(init()); + + assert_eq!(*m.lock().unwrap(), init()); + m.set(value()).unwrap(); + assert_eq!(*m.lock().unwrap(), value()); + } + + inner(|| NonCopy(10), || NonCopy(20)); + inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20)); +} + +#[test] +fn test_set_poison() { + fn inner(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T) + where + T: Debug + Eq, + { + let m = new_poisoned_mutex(init()); + + match m.set(value()) { + Err(e) => { + assert_eq!(e.into_inner(), value()); + assert_eq!(m.into_inner().unwrap_err().into_inner(), init()); + } + Ok(x) => panic!("set of poisoned Mutex is Ok: {x:?}"), + } + } + + inner(|| NonCopy(10), || NonCopy(20)); + inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20)); +} + +#[test] +fn test_replace() { + fn inner(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T) + where + T: Debug + Eq, + { + let m = Mutex::new(init()); + + assert_eq!(*m.lock().unwrap(), init()); + assert_eq!(m.replace(value()).unwrap(), init()); + assert_eq!(*m.lock().unwrap(), value()); + } + + inner(|| NonCopy(10), || NonCopy(20)); + inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20)); +} + +#[test] +fn test_replace_poison() { + fn inner(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T) + where + T: Debug + Eq, + { + let m = new_poisoned_mutex(init()); + + match m.replace(value()) { + Err(e) => { + assert_eq!(e.into_inner(), value()); + assert_eq!(m.into_inner().unwrap_err().into_inner(), init()); + } + Ok(x) => panic!("replace of poisoned Mutex is Ok: {x:?}"), + } + } + + inner(|| NonCopy(10), || NonCopy(20)); + inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20)); +} + #[test] fn test_mutex_arc_condvar() { let packet = Packet(Arc::new((Mutex::new(false), Condvar::new()))); @@ -269,7 +384,7 @@ fn test_mapping_mapped_guard() { fn panic_while_mapping_unlocked_poison() { let lock = Mutex::new(()); - let _ = crate::panic::catch_unwind(|| { + let _ = panic::catch_unwind(|| { let guard = lock.lock().unwrap(); let _guard = MutexGuard::map::<(), _>(guard, |_| panic!()); }); @@ -282,7 +397,7 @@ fn panic_while_mapping_unlocked_poison() { Err(TryLockError::Poisoned(_)) => {} } - let _ = crate::panic::catch_unwind(|| { + let _ = panic::catch_unwind(|| { let guard = lock.lock().unwrap(); let _guard = MutexGuard::try_map::<(), _>(guard, |_| panic!()); }); @@ -295,7 +410,7 @@ fn panic_while_mapping_unlocked_poison() { Err(TryLockError::Poisoned(_)) => {} } - let _ = crate::panic::catch_unwind(|| { + let _ = panic::catch_unwind(|| { let guard = lock.lock().unwrap(); let guard = MutexGuard::map::<(), _>(guard, |val| val); let _guard = MappedMutexGuard::map::<(), _>(guard, |_| panic!()); @@ -309,7 +424,7 @@ fn panic_while_mapping_unlocked_poison() { Err(TryLockError::Poisoned(_)) => {} } - let _ = crate::panic::catch_unwind(|| { + let _ = panic::catch_unwind(|| { let guard = lock.lock().unwrap(); let guard = MutexGuard::map::<(), _>(guard, |val| val); let _guard = MappedMutexGuard::try_map::<(), _>(guard, |_| panic!()); diff --git a/std/src/sync/once.rs b/std/src/sync/poison/once.rs similarity index 100% rename from std/src/sync/once.rs rename to std/src/sync/poison/once.rs diff --git a/std/src/sync/once/tests.rs b/std/src/sync/poison/once/tests.rs similarity index 100% rename from std/src/sync/once/tests.rs rename to std/src/sync/poison/once/tests.rs diff --git a/std/src/sync/rwlock.rs b/std/src/sync/poison/rwlock.rs similarity index 91% rename from std/src/sync/rwlock.rs rename to std/src/sync/poison/rwlock.rs index d55d1c80dcae0..1519baf99a8fd 100644 --- a/std/src/sync/rwlock.rs +++ b/std/src/sync/poison/rwlock.rs @@ -4,7 +4,7 @@ mod tests; use crate::cell::UnsafeCell; use crate::fmt; use crate::marker::PhantomData; -use crate::mem::{ManuallyDrop, forget}; +use crate::mem::{self, ManuallyDrop, forget}; use crate::ops::{Deref, DerefMut}; use crate::ptr::NonNull; use crate::sync::{LockResult, PoisonError, TryLockError, TryLockResult, poison}; @@ -224,6 +224,103 @@ impl RwLock { pub const fn new(t: T) -> RwLock { RwLock { inner: sys::RwLock::new(), poison: poison::Flag::new(), data: UnsafeCell::new(t) } } + + /// Returns the contained value by cloning it. + /// + /// # Errors + /// + /// This function will return an error if the `RwLock` is poisoned. An + /// `RwLock` is poisoned whenever a writer panics while holding an exclusive + /// lock. + /// + /// # Examples + /// + /// ``` + /// #![feature(lock_value_accessors)] + /// + /// use std::sync::RwLock; + /// + /// let mut lock = RwLock::new(7); + /// + /// assert_eq!(lock.get_cloned().unwrap(), 7); + /// ``` + #[unstable(feature = "lock_value_accessors", issue = "133407")] + pub fn get_cloned(&self) -> Result> + where + T: Clone, + { + match self.read() { + Ok(guard) => Ok((*guard).clone()), + Err(_) => Err(PoisonError::new(())), + } + } + + /// Sets the contained value. + /// + /// # Errors + /// + /// This function will return an error containing the provided `value` if + /// the `RwLock` is poisoned. An `RwLock` is poisoned whenever a writer + /// panics while holding an exclusive lock. + /// + /// # Examples + /// + /// ``` + /// #![feature(lock_value_accessors)] + /// + /// use std::sync::RwLock; + /// + /// let mut lock = RwLock::new(7); + /// + /// assert_eq!(lock.get_cloned().unwrap(), 7); + /// lock.set(11).unwrap(); + /// assert_eq!(lock.get_cloned().unwrap(), 11); + /// ``` + #[unstable(feature = "lock_value_accessors", issue = "133407")] + pub fn set(&self, value: T) -> Result<(), PoisonError> { + if mem::needs_drop::() { + // If the contained value has non-trivial destructor, we + // call that destructor after the lock being released. + self.replace(value).map(drop) + } else { + match self.write() { + Ok(mut guard) => { + *guard = value; + + Ok(()) + } + Err(_) => Err(PoisonError::new(value)), + } + } + } + + /// Replaces the contained value with `value`, and returns the old contained value. + /// + /// # Errors + /// + /// This function will return an error containing the provided `value` if + /// the `RwLock` is poisoned. An `RwLock` is poisoned whenever a writer + /// panics while holding an exclusive lock. + /// + /// # Examples + /// + /// ``` + /// #![feature(lock_value_accessors)] + /// + /// use std::sync::RwLock; + /// + /// let mut lock = RwLock::new(7); + /// + /// assert_eq!(lock.replace(11).unwrap(), 7); + /// assert_eq!(lock.get_cloned().unwrap(), 11); + /// ``` + #[unstable(feature = "lock_value_accessors", issue = "133407")] + pub fn replace(&self, value: T) -> LockResult { + match self.write() { + Ok(mut guard) => Ok(mem::replace(&mut *guard, value)), + Err(_) => Err(PoisonError::new(value)), + } + } } impl RwLock { @@ -244,7 +341,8 @@ impl RwLock { /// This function will return an error if the `RwLock` is poisoned. An /// `RwLock` is poisoned whenever a writer panics while holding an exclusive /// lock. The failure will occur immediately after the lock has been - /// acquired. + /// acquired. The acquired lock guard will be contained in the returned + /// error. /// /// # Panics /// @@ -292,7 +390,8 @@ impl RwLock { /// This function will return the [`Poisoned`] error if the `RwLock` is /// poisoned. An `RwLock` is poisoned whenever a writer panics while holding /// an exclusive lock. `Poisoned` will only be returned if the lock would - /// have otherwise been acquired. + /// have otherwise been acquired. An acquired lock guard will be contained + /// in the returned error. /// /// This function will return the [`WouldBlock`] error if the `RwLock` could /// not be acquired because it was already locked exclusively. @@ -337,7 +436,8 @@ impl RwLock { /// /// This function will return an error if the `RwLock` is poisoned. An /// `RwLock` is poisoned whenever a writer panics while holding an exclusive - /// lock. An error will be returned when the lock is acquired. + /// lock. An error will be returned when the lock is acquired. The acquired + /// lock guard will be contained in the returned error. /// /// # Panics /// @@ -380,7 +480,8 @@ impl RwLock { /// This function will return the [`Poisoned`] error if the `RwLock` is /// poisoned. An `RwLock` is poisoned whenever a writer panics while holding /// an exclusive lock. `Poisoned` will only be returned if the lock would - /// have otherwise been acquired. + /// have otherwise been acquired. An acquired lock guard will be contained + /// in the returned error. /// /// This function will return the [`WouldBlock`] error if the `RwLock` could /// not be acquired because it was already locked exclusively. @@ -481,10 +582,10 @@ impl RwLock { /// /// # Errors /// - /// This function will return an error if the `RwLock` is poisoned. An - /// `RwLock` is poisoned whenever a writer panics while holding an exclusive - /// lock. An error will only be returned if the lock would have otherwise - /// been acquired. + /// This function will return an error containing the underlying data if + /// the `RwLock` is poisoned. An `RwLock` is poisoned whenever a writer + /// panics while holding an exclusive lock. An error will only be returned + /// if the lock would have otherwise been acquired. /// /// # Examples /// @@ -514,10 +615,11 @@ impl RwLock { /// /// # Errors /// - /// This function will return an error if the `RwLock` is poisoned. An - /// `RwLock` is poisoned whenever a writer panics while holding an exclusive - /// lock. An error will only be returned if the lock would have otherwise - /// been acquired. + /// This function will return an error containing a mutable reference to + /// the underlying data if the `RwLock` is poisoned. An `RwLock` is + /// poisoned whenever a writer panics while holding an exclusive lock. + /// An error will only be returned if the lock would have otherwise been + /// acquired. /// /// # Examples /// diff --git a/std/src/sync/rwlock/tests.rs b/std/src/sync/poison/rwlock/tests.rs similarity index 81% rename from std/src/sync/rwlock/tests.rs rename to std/src/sync/poison/rwlock/tests.rs index 29cad4400f189..057c2f1a5d7a7 100644 --- a/std/src/sync/rwlock/tests.rs +++ b/std/src/sync/poison/rwlock/tests.rs @@ -1,16 +1,37 @@ use rand::Rng; +use crate::fmt::Debug; +use crate::ops::FnMut; +use crate::panic::{self, AssertUnwindSafe}; use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::sync::mpsc::channel; use crate::sync::{ Arc, MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard, TryLockError, }; -use crate::thread; +use crate::{hint, mem, thread}; #[derive(Eq, PartialEq, Debug)] struct NonCopy(i32); +#[derive(Eq, PartialEq, Debug)] +struct NonCopyNeedsDrop(i32); + +impl Drop for NonCopyNeedsDrop { + fn drop(&mut self) { + hint::black_box(()); + } +} + +#[test] +fn test_needs_drop() { + assert!(!mem::needs_drop::()); + assert!(mem::needs_drop::()); +} + +#[derive(Clone, Eq, PartialEq, Debug)] +struct Cloneable(i32); + #[test] fn smoke() { let l = RwLock::new(()); @@ -255,6 +276,21 @@ fn test_rwlock_try_write() { drop(mapped_read_guard); } +fn new_poisoned_rwlock(value: T) -> RwLock { + let lock = RwLock::new(value); + + let catch_unwind_result = panic::catch_unwind(AssertUnwindSafe(|| { + let _guard = lock.write().unwrap(); + + panic!("test panic to poison RwLock"); + })); + + assert!(catch_unwind_result.is_err()); + assert!(lock.is_poisoned()); + + lock +} + #[test] fn test_into_inner() { let m = RwLock::new(NonCopy(10)); @@ -281,21 +317,31 @@ fn test_into_inner_drop() { #[test] fn test_into_inner_poison() { - let m = Arc::new(RwLock::new(NonCopy(10))); - let m2 = m.clone(); - let _ = thread::spawn(move || { - let _lock = m2.write().unwrap(); - panic!("test panic in inner thread to poison RwLock"); - }) - .join(); + let m = new_poisoned_rwlock(NonCopy(10)); - assert!(m.is_poisoned()); - match Arc::try_unwrap(m).unwrap().into_inner() { + match m.into_inner() { Err(e) => assert_eq!(e.into_inner(), NonCopy(10)), Ok(x) => panic!("into_inner of poisoned RwLock is Ok: {x:?}"), } } +#[test] +fn test_get_cloned() { + let m = RwLock::new(Cloneable(10)); + + assert_eq!(m.get_cloned().unwrap(), Cloneable(10)); +} + +#[test] +fn test_get_cloned_poison() { + let m = new_poisoned_rwlock(Cloneable(10)); + + match m.get_cloned() { + Err(e) => assert_eq!(e.into_inner(), ()), + Ok(x) => panic!("get of poisoned RwLock is Ok: {x:?}"), + } +} + #[test] fn test_get_mut() { let mut m = RwLock::new(NonCopy(10)); @@ -305,21 +351,90 @@ fn test_get_mut() { #[test] fn test_get_mut_poison() { - let m = Arc::new(RwLock::new(NonCopy(10))); - let m2 = m.clone(); - let _ = thread::spawn(move || { - let _lock = m2.write().unwrap(); - panic!("test panic in inner thread to poison RwLock"); - }) - .join(); + let mut m = new_poisoned_rwlock(NonCopy(10)); - assert!(m.is_poisoned()); - match Arc::try_unwrap(m).unwrap().get_mut() { + match m.get_mut() { Err(e) => assert_eq!(*e.into_inner(), NonCopy(10)), Ok(x) => panic!("get_mut of poisoned RwLock is Ok: {x:?}"), } } +#[test] +fn test_set() { + fn inner(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T) + where + T: Debug + Eq, + { + let m = RwLock::new(init()); + + assert_eq!(*m.read().unwrap(), init()); + m.set(value()).unwrap(); + assert_eq!(*m.read().unwrap(), value()); + } + + inner(|| NonCopy(10), || NonCopy(20)); + inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20)); +} + +#[test] +fn test_set_poison() { + fn inner(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T) + where + T: Debug + Eq, + { + let m = new_poisoned_rwlock(init()); + + match m.set(value()) { + Err(e) => { + assert_eq!(e.into_inner(), value()); + assert_eq!(m.into_inner().unwrap_err().into_inner(), init()); + } + Ok(x) => panic!("set of poisoned RwLock is Ok: {x:?}"), + } + } + + inner(|| NonCopy(10), || NonCopy(20)); + inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20)); +} + +#[test] +fn test_replace() { + fn inner(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T) + where + T: Debug + Eq, + { + let m = RwLock::new(init()); + + assert_eq!(*m.read().unwrap(), init()); + assert_eq!(m.replace(value()).unwrap(), init()); + assert_eq!(*m.read().unwrap(), value()); + } + + inner(|| NonCopy(10), || NonCopy(20)); + inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20)); +} + +#[test] +fn test_replace_poison() { + fn inner(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T) + where + T: Debug + Eq, + { + let m = new_poisoned_rwlock(init()); + + match m.replace(value()) { + Err(e) => { + assert_eq!(e.into_inner(), value()); + assert_eq!(m.into_inner().unwrap_err().into_inner(), init()); + } + Ok(x) => panic!("replace of poisoned RwLock is Ok: {x:?}"), + } + } + + inner(|| NonCopy(10), || NonCopy(20)); + inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20)); +} + #[test] fn test_read_guard_covariance() { fn do_stuff<'a>(_: RwLockReadGuard<'_, &'a i32>, _: &'a i32) {} @@ -370,7 +485,7 @@ fn test_mapping_mapped_guard() { fn panic_while_mapping_read_unlocked_no_poison() { let lock = RwLock::new(()); - let _ = crate::panic::catch_unwind(|| { + let _ = panic::catch_unwind(|| { let guard = lock.read().unwrap(); let _guard = RwLockReadGuard::map::<(), _>(guard, |_| panic!()); }); @@ -385,7 +500,7 @@ fn panic_while_mapping_read_unlocked_no_poison() { } } - let _ = crate::panic::catch_unwind(|| { + let _ = panic::catch_unwind(|| { let guard = lock.read().unwrap(); let _guard = RwLockReadGuard::try_map::<(), _>(guard, |_| panic!()); }); @@ -400,7 +515,7 @@ fn panic_while_mapping_read_unlocked_no_poison() { } } - let _ = crate::panic::catch_unwind(|| { + let _ = panic::catch_unwind(|| { let guard = lock.read().unwrap(); let guard = RwLockReadGuard::map::<(), _>(guard, |val| val); let _guard = MappedRwLockReadGuard::map::<(), _>(guard, |_| panic!()); @@ -416,7 +531,7 @@ fn panic_while_mapping_read_unlocked_no_poison() { } } - let _ = crate::panic::catch_unwind(|| { + let _ = panic::catch_unwind(|| { let guard = lock.read().unwrap(); let guard = RwLockReadGuard::map::<(), _>(guard, |val| val); let _guard = MappedRwLockReadGuard::try_map::<(), _>(guard, |_| panic!()); @@ -439,7 +554,7 @@ fn panic_while_mapping_read_unlocked_no_poison() { fn panic_while_mapping_write_unlocked_poison() { let lock = RwLock::new(()); - let _ = crate::panic::catch_unwind(|| { + let _ = panic::catch_unwind(|| { let guard = lock.write().unwrap(); let _guard = RwLockWriteGuard::map::<(), _>(guard, |_| panic!()); }); @@ -452,7 +567,7 @@ fn panic_while_mapping_write_unlocked_poison() { Err(TryLockError::Poisoned(_)) => {} } - let _ = crate::panic::catch_unwind(|| { + let _ = panic::catch_unwind(|| { let guard = lock.write().unwrap(); let _guard = RwLockWriteGuard::try_map::<(), _>(guard, |_| panic!()); }); @@ -467,7 +582,7 @@ fn panic_while_mapping_write_unlocked_poison() { Err(TryLockError::Poisoned(_)) => {} } - let _ = crate::panic::catch_unwind(|| { + let _ = panic::catch_unwind(|| { let guard = lock.write().unwrap(); let guard = RwLockWriteGuard::map::<(), _>(guard, |val| val); let _guard = MappedRwLockWriteGuard::map::<(), _>(guard, |_| panic!()); @@ -483,7 +598,7 @@ fn panic_while_mapping_write_unlocked_poison() { Err(TryLockError::Poisoned(_)) => {} } - let _ = crate::panic::catch_unwind(|| { + let _ = panic::catch_unwind(|| { let guard = lock.write().unwrap(); let guard = RwLockWriteGuard::map::<(), _>(guard, |val| val); let _guard = MappedRwLockWriteGuard::try_map::<(), _>(guard, |_| panic!()); @@ -511,12 +626,15 @@ fn test_downgrade_basic() { } #[test] +// FIXME: On macOS we use a provenance-incorrect implementation and Miri catches that issue. +// See for details. +#[cfg_attr(all(miri, target_os = "macos"), ignore)] fn test_downgrade_observe() { // Taken from the test `test_rwlock_downgrade` from: // https://github.com/Amanieu/parking_lot/blob/master/src/rwlock.rs const W: usize = 20; - const N: usize = 100; + const N: usize = if cfg!(miri) { 40 } else { 100 }; // This test spawns `W` writer threads, where each will increment a counter `N` times, ensuring // that the value they wrote has not changed after downgrading. diff --git a/std/src/sys/backtrace.rs b/std/src/sys/backtrace.rs index 4d939e175cf2e..efa6a896dad8f 100644 --- a/std/src/sys/backtrace.rs +++ b/std/src/sys/backtrace.rs @@ -58,8 +58,8 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt:: let mut res = Ok(()); let mut omitted_count: usize = 0; let mut first_omit = true; - // Start immediately if we're not using a short backtrace. - let mut start = print_fmt != PrintFmt::Short; + // If we're using a short backtrace, ignore all frames until we're told to start printing. + let mut print = print_fmt != PrintFmt::Short; set_image_base(); // SAFETY: we roll our own locking in this town unsafe { @@ -72,27 +72,25 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt:: backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| { hit = true; - // Any frames between `__rust_begin_short_backtrace` and `__rust_end_short_backtrace` - // are omitted from the backtrace in short mode, `__rust_end_short_backtrace` will be - // called before the panic hook, so we won't ignore any frames if there is no - // invoke of `__rust_begin_short_backtrace`. + // `__rust_end_short_backtrace` means we are done hiding symbols + // for now. Print until we see `__rust_begin_short_backtrace`. if print_fmt == PrintFmt::Short { if let Some(sym) = symbol.name().and_then(|s| s.as_str()) { - if start && sym.contains("__rust_begin_short_backtrace") { - start = false; + if sym.contains("__rust_end_short_backtrace") { + print = true; return; } - if sym.contains("__rust_end_short_backtrace") { - start = true; + if print && sym.contains("__rust_begin_short_backtrace") { + print = false; return; } - if !start { + if !print { omitted_count += 1; } } } - if start { + if print { if omitted_count > 0 { debug_assert!(print_fmt == PrintFmt::Short); // only print the message between the middle of frames @@ -112,7 +110,7 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt:: }); #[cfg(target_os = "nto")] if libc::__my_thread_exit as *mut libc::c_void == frame.ip() { - if !hit && start { + if !hit && print { use crate::backtrace_rs::SymbolName; res = bt_fmt.frame().print_raw( frame.ip(), @@ -123,7 +121,7 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt:: } return false; } - if !hit && start { + if !hit && print { res = bt_fmt.frame().print_raw(frame.ip(), None, None, None); } diff --git a/std/src/sys/cmath.rs b/std/src/sys/cmath.rs index 2997e908fa1b2..ee36127cfdf1e 100644 --- a/std/src/sys/cmath.rs +++ b/std/src/sys/cmath.rs @@ -26,6 +26,7 @@ extern "C" { pub fn tgamma(n: f64) -> f64; pub fn tgammaf(n: f32) -> f32; pub fn lgamma_r(n: f64, s: &mut i32) -> f64; + #[cfg(not(target_os = "aix"))] pub fn lgammaf_r(n: f32, s: &mut i32) -> f32; pub fn acosf128(n: f128) -> f128; @@ -56,6 +57,13 @@ extern "C" { }} } +// On AIX, we don't have lgammaf_r only the f64 version, so we can +// use the f64 version lgamma_r +#[cfg(target_os = "aix")] +pub unsafe fn lgammaf_r(n: f32, s: &mut i32) -> f32 { + lgamma_r(n.into(), s) as f32 +} + // On 32-bit x86 MSVC these functions aren't defined, so we just define shims // which promote everything to f64, perform the calculation, and then demote // back to f32. While not precisely correct should be "correct enough" for now. diff --git a/std/src/sys/pal/common/small_c_string.rs b/std/src/sys/pal/common/small_c_string.rs index 3c96714b5c58c..f54505a856e05 100644 --- a/std/src/sys/pal/common/small_c_string.rs +++ b/std/src/sys/pal/common/small_c_string.rs @@ -11,7 +11,7 @@ const MAX_STACK_ALLOCATION: usize = 384; const MAX_STACK_ALLOCATION: usize = 32; const NUL_ERR: io::Error = - io::const_io_error!(io::ErrorKind::InvalidInput, "file name contained an unexpected NUL byte"); + io::const_error!(io::ErrorKind::InvalidInput, "file name contained an unexpected NUL byte"); #[inline] pub fn run_path_with_cstr(path: &Path, f: &dyn Fn(&CStr) -> io::Result) -> io::Result { diff --git a/std/src/sys/pal/hermit/fs.rs b/std/src/sys/pal/hermit/fs.rs index 17d15ed2e5045..783623552bb17 100644 --- a/std/src/sys/pal/hermit/fs.rs +++ b/std/src/sys/pal/hermit/fs.rs @@ -3,7 +3,7 @@ use super::hermit_abi::{ self, DT_DIR, DT_LNK, DT_REG, DT_UNKNOWN, O_APPEND, O_CREAT, O_DIRECTORY, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG, dirent64, stat as stat_struct, }; -use crate::ffi::{CStr, OsStr, OsString}; +use crate::ffi::{CStr, OsStr, OsString, c_char}; use crate::io::{self, BorrowedCursor, Error, ErrorKind, IoSlice, IoSliceMut, SeekFrom}; use crate::os::hermit::ffi::OsStringExt; use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; @@ -135,7 +135,7 @@ impl FileAttr { S_IFREG => DT_REG, _ => DT_UNKNOWN, }; - FileType { mode: mode } + FileType { mode } } } @@ -204,7 +204,7 @@ impl Iterator for ReadDir { // the size of dirent64. The file name is always a C string and terminated by `\0`. // Consequently, we are able to ignore the last byte. let name_bytes = - unsafe { CStr::from_ptr(&dir.d_name as *const _ as *const i8).to_bytes() }; + unsafe { CStr::from_ptr(&dir.d_name as *const _ as *const c_char).to_bytes() }; let entry = DirEntry { root: self.inner.root.clone(), ino: dir.d_ino, @@ -294,7 +294,7 @@ impl OpenOptions { (false, _, true) => Ok(O_WRONLY | O_APPEND), (true, _, true) => Ok(O_RDWR | O_APPEND), (false, false, false) => { - Err(io::const_io_error!(ErrorKind::InvalidInput, "invalid access mode")) + Err(io::const_error!(ErrorKind::InvalidInput, "invalid access mode")) } } } @@ -304,18 +304,16 @@ impl OpenOptions { (true, false) => {} (false, false) => { if self.truncate || self.create || self.create_new { - return Err(io::const_io_error!( - ErrorKind::InvalidInput, - "invalid creation mode", - )); + return Err( + io::const_error!(ErrorKind::InvalidInput, "invalid creation mode",), + ); } } (_, true) => { if self.truncate && !self.create_new { - return Err(io::const_io_error!( - ErrorKind::InvalidInput, - "invalid creation mode", - )); + return Err( + io::const_error!(ErrorKind::InvalidInput, "invalid creation mode",), + ); } } } @@ -447,7 +445,7 @@ impl DirBuilder { pub fn mkdir(&self, path: &Path) -> io::Result<()> { run_path_with_cstr(path, &|path| { - cvt(unsafe { hermit_abi::mkdir(path.as_ptr(), self.mode.into()) }).map(|_| ()) + cvt(unsafe { hermit_abi::mkdir(path.as_ptr().cast(), self.mode.into()) }).map(|_| ()) }) } diff --git a/std/src/sys/pal/hermit/mod.rs b/std/src/sys/pal/hermit/mod.rs index b62afb40a615f..d833c9d632c6d 100644 --- a/std/src/sys/pal/hermit/mod.rs +++ b/std/src/sys/pal/hermit/mod.rs @@ -42,7 +42,7 @@ pub fn unsupported() -> crate::io::Result { } pub fn unsupported_err() -> crate::io::Error { - crate::io::const_io_error!( + crate::io::const_error!( crate::io::ErrorKind::Unsupported, "operation not supported on HermitCore yet", ) @@ -85,7 +85,7 @@ pub unsafe extern "C" fn runtime_entry( } // initialize environment - os::init_environment(env as *const *const i8); + os::init_environment(env); let result = unsafe { main(argc as isize, argv) }; diff --git a/std/src/sys/pal/hermit/net.rs b/std/src/sys/pal/hermit/net.rs index d9baa091a2321..4e12374203e38 100644 --- a/std/src/sys/pal/hermit/net.rs +++ b/std/src/sys/pal/hermit/net.rs @@ -87,7 +87,7 @@ impl Socket { loop { let elapsed = start.elapsed(); if elapsed >= timeout { - return Err(io::const_io_error!(io::ErrorKind::TimedOut, "connection timed out")); + return Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out")); } let timeout = timeout - elapsed; @@ -114,7 +114,7 @@ impl Socket { // for POLLHUP rather than read readiness if pollfd.revents & netc::POLLHUP != 0 { let e = self.take_error()?.unwrap_or_else(|| { - io::const_io_error!( + io::const_error!( io::ErrorKind::Uncategorized, "no error set after POLLHUP", ) diff --git a/std/src/sys/pal/hermit/os.rs b/std/src/sys/pal/hermit/os.rs index f8ea80afa43f1..791cdb1e57e7d 100644 --- a/std/src/sys/pal/hermit/os.rs +++ b/std/src/sys/pal/hermit/os.rs @@ -3,7 +3,7 @@ use core::slice::memchr; use super::hermit_abi; use crate::collections::HashMap; use crate::error::Error as StdError; -use crate::ffi::{CStr, OsStr, OsString}; +use crate::ffi::{CStr, OsStr, OsString, c_char}; use crate::marker::PhantomData; use crate::os::hermit::ffi::OsStringExt; use crate::path::{self, PathBuf}; @@ -70,7 +70,7 @@ pub fn current_exe() -> io::Result { static ENV: Mutex>> = Mutex::new(None); -pub fn init_environment(env: *const *const i8) { +pub fn init_environment(env: *const *const c_char) { let mut guard = ENV.lock().unwrap(); let map = guard.insert(HashMap::new()); diff --git a/std/src/sys/pal/hermit/thread.rs b/std/src/sys/pal/hermit/thread.rs index 41f2c3e212355..4a7afddbec107 100644 --- a/std/src/sys/pal/hermit/thread.rs +++ b/std/src/sys/pal/hermit/thread.rs @@ -41,9 +41,9 @@ impl Thread { unsafe { drop(Box::from_raw(p)); } - Err(io::const_io_error!(io::ErrorKind::Uncategorized, "Unable to create thread!")) + Err(io::const_error!(io::ErrorKind::Uncategorized, "Unable to create thread!")) } else { - Ok(Thread { tid: tid }) + Ok(Thread { tid }) }; extern "C" fn thread_start(main: usize) { diff --git a/std/src/sys/pal/hermit/time.rs b/std/src/sys/pal/hermit/time.rs index e0b6eb76b03af..f76a5f96c8750 100644 --- a/std/src/sys/pal/hermit/time.rs +++ b/std/src/sys/pal/hermit/time.rs @@ -22,7 +22,7 @@ impl Timespec { const fn new(tv_sec: i64, tv_nsec: i32) -> Timespec { assert!(tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC); // SAFETY: The assert above checks tv_nsec is within the valid range - Timespec { t: timespec { tv_sec: tv_sec, tv_nsec: tv_nsec } } + Timespec { t: timespec { tv_sec, tv_nsec } } } fn sub_timespec(&self, other: &Timespec) -> Result { diff --git a/std/src/sys/pal/sgx/fd.rs b/std/src/sys/pal/sgx/fd.rs index c41b527cff798..3bb3189a1d127 100644 --- a/std/src/sys/pal/sgx/fd.rs +++ b/std/src/sys/pal/sgx/fd.rs @@ -12,7 +12,7 @@ pub struct FileDesc { impl FileDesc { pub fn new(fd: Fd) -> FileDesc { - FileDesc { fd: fd } + FileDesc { fd } } pub fn raw(&self) -> Fd { diff --git a/std/src/sys/pal/sgx/mod.rs b/std/src/sys/pal/sgx/mod.rs index 586ccd18c2f57..ce8a2fed4bc6b 100644 --- a/std/src/sys/pal/sgx/mod.rs +++ b/std/src/sys/pal/sgx/mod.rs @@ -48,7 +48,7 @@ pub fn unsupported() -> crate::io::Result { } pub fn unsupported_err() -> crate::io::Error { - crate::io::const_io_error!(ErrorKind::Unsupported, "operation not supported on SGX yet") + crate::io::const_error!(ErrorKind::Unsupported, "operation not supported on SGX yet") } /// This function is used to implement various functions that doesn't exist, @@ -59,7 +59,7 @@ pub fn unsupported_err() -> crate::io::Error { pub fn sgx_ineffective(v: T) -> crate::io::Result { static SGX_INEFFECTIVE_ERROR: AtomicBool = AtomicBool::new(false); if SGX_INEFFECTIVE_ERROR.load(Ordering::Relaxed) { - Err(crate::io::const_io_error!( + Err(crate::io::const_error!( ErrorKind::Uncategorized, "operation can't be trusted to have any effect on SGX", )) diff --git a/std/src/sys/pal/solid/fs.rs b/std/src/sys/pal/solid/fs.rs index 776a96ff3b7ba..fa2e470d6b601 100644 --- a/std/src/sys/pal/solid/fs.rs +++ b/std/src/sys/pal/solid/fs.rs @@ -12,15 +12,12 @@ use crate::sys::unsupported; pub use crate::sys_common::fs::exists; use crate::sys_common::ignore_notfound; +type CIntNotMinusOne = core::num::niche_types::NotAllOnes; + /// A file descriptor. #[derive(Clone, Copy)] -#[rustc_layout_scalar_valid_range_start(0)] -// libstd/os/raw/mod.rs assures me that every libstd-supported platform has a -// 32-bit c_int. Below is -2, in two's complement, but that only works out -// because c_int is 32 bits. -#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] struct FileDesc { - fd: c_int, + fd: CIntNotMinusOne, } impl FileDesc { @@ -29,12 +26,13 @@ impl FileDesc { assert_ne!(fd, -1i32); // Safety: we just asserted that the value is in the valid range and // isn't `-1` (the only value bigger than `0xFF_FF_FF_FE` unsigned) - unsafe { FileDesc { fd } } + let fd = unsafe { CIntNotMinusOne::new_unchecked(fd) }; + FileDesc { fd } } #[inline] fn raw(&self) -> c_int { - self.fd + self.fd.as_inner() } } @@ -303,7 +301,7 @@ fn cstr(path: &Path) -> io::Result { if !path.starts_with(br"\") { // Relative paths aren't supported - return Err(crate::io::const_io_error!( + return Err(crate::io::const_error!( crate::io::ErrorKind::Unsupported, "relative path is not supported on this platform", )); @@ -314,10 +312,7 @@ fn cstr(path: &Path) -> io::Result { let wrapped_path = [SAFE_PREFIX, &path, &[0]].concat(); CString::from_vec_with_nul(wrapped_path).map_err(|_| { - crate::io::const_io_error!( - io::ErrorKind::InvalidInput, - "path provided contains a nul byte", - ) + crate::io::const_error!(io::ErrorKind::InvalidInput, "path provided contains a nul byte",) }) } @@ -512,7 +507,7 @@ impl fmt::Debug for File { pub fn unlink(p: &Path) -> io::Result<()> { if stat(p)?.file_type().is_dir() { - Err(io::const_io_error!(io::ErrorKind::IsADirectory, "is a directory")) + Err(io::const_error!(io::ErrorKind::IsADirectory, "is a directory")) } else { error::SolidError::err_if_negative(unsafe { abi::SOLID_FS_Unlink(cstr(p)?.as_ptr()) }) .map_err(|e| e.as_io_error())?; @@ -542,7 +537,7 @@ pub fn rmdir(p: &Path) -> io::Result<()> { .map_err(|e| e.as_io_error())?; Ok(()) } else { - Err(io::const_io_error!(io::ErrorKind::NotADirectory, "not a directory")) + Err(io::const_error!(io::ErrorKind::NotADirectory, "not a directory")) } } @@ -570,7 +565,7 @@ pub fn remove_dir_all(path: &Path) -> io::Result<()> { pub fn readlink(p: &Path) -> io::Result { // This target doesn't support symlinks stat(p)?; - Err(io::const_io_error!(io::ErrorKind::InvalidInput, "not a symbolic link")) + Err(io::const_error!(io::ErrorKind::InvalidInput, "not a symbolic link")) } pub fn symlink(_original: &Path, _link: &Path) -> io::Result<()> { diff --git a/std/src/sys/pal/solid/net.rs b/std/src/sys/pal/solid/net.rs index c0818ecd856d2..5f6436807e27e 100644 --- a/std/src/sys/pal/solid/net.rs +++ b/std/src/sys/pal/solid/net.rs @@ -175,7 +175,7 @@ impl Socket { }; match n { - 0 => Err(io::const_io_error!(io::ErrorKind::TimedOut, "connection timed out")), + 0 => Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out")), _ => { let can_write = writefds.num_fds != 0; if !can_write { diff --git a/std/src/sys/pal/solid/os.rs b/std/src/sys/pal/solid/os.rs index d8afcb91f67f2..57c28aed3b293 100644 --- a/std/src/sys/pal/solid/os.rs +++ b/std/src/sys/pal/solid/os.rs @@ -204,7 +204,7 @@ pub unsafe fn unsetenv(n: &OsStr) -> io::Result<()> { /// In kmclib, `setenv` and `unsetenv` don't always set `errno`, so this /// function just returns a generic error. fn cvt_env(t: c_int) -> io::Result { - if t == -1 { Err(io::const_io_error!(io::ErrorKind::Uncategorized, "failure")) } else { Ok(t) } + if t == -1 { Err(io::const_error!(io::ErrorKind::Uncategorized, "failure")) } else { Ok(t) } } pub fn temp_dir() -> PathBuf { diff --git a/std/src/sys/pal/teeos/mod.rs b/std/src/sys/pal/teeos/mod.rs index 60a227afb84e3..a9900f55b1926 100644 --- a/std/src/sys/pal/teeos/mod.rs +++ b/std/src/sys/pal/teeos/mod.rs @@ -27,6 +27,14 @@ pub mod thread; #[path = "../unix/time.rs"] pub mod time; +#[path = "../unix/sync"] +pub mod sync { + mod condvar; + mod mutex; + pub use condvar::Condvar; + pub use mutex::Mutex; +} + use crate::io::ErrorKind; pub fn abort_internal() -> ! { @@ -63,7 +71,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind { libc::ECONNREFUSED => ConnectionRefused, libc::ECONNRESET => ConnectionReset, libc::EDEADLK => Deadlock, - libc::EDQUOT => FilesystemQuotaExceeded, + libc::EDQUOT => QuotaExceeded, libc::EEXIST => AlreadyExists, libc::EFBIG => FileTooLarge, libc::EHOSTUNREACH => HostUnreachable, diff --git a/std/src/sys/pal/uefi/fs.rs b/std/src/sys/pal/uefi/fs.rs new file mode 100644 index 0000000000000..9585ec24f687d --- /dev/null +++ b/std/src/sys/pal/uefi/fs.rs @@ -0,0 +1,344 @@ +use crate::ffi::OsString; +use crate::fmt; +use crate::hash::{Hash, Hasher}; +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; +use crate::path::{Path, PathBuf}; +use crate::sys::time::SystemTime; +use crate::sys::unsupported; + +pub struct File(!); + +pub struct FileAttr(!); + +pub struct ReadDir(!); + +pub struct DirEntry(!); + +#[derive(Clone, Debug)] +pub struct OpenOptions {} + +#[derive(Copy, Clone, Debug, Default)] +pub struct FileTimes {} + +pub struct FilePermissions(!); + +pub struct FileType(!); + +#[derive(Debug)] +pub struct DirBuilder {} + +impl FileAttr { + pub fn size(&self) -> u64 { + self.0 + } + + pub fn perm(&self) -> FilePermissions { + self.0 + } + + pub fn file_type(&self) -> FileType { + self.0 + } + + pub fn modified(&self) -> io::Result { + self.0 + } + + pub fn accessed(&self) -> io::Result { + self.0 + } + + pub fn created(&self) -> io::Result { + self.0 + } +} + +impl Clone for FileAttr { + fn clone(&self) -> FileAttr { + self.0 + } +} + +impl FilePermissions { + pub fn readonly(&self) -> bool { + self.0 + } + + pub fn set_readonly(&mut self, _readonly: bool) { + self.0 + } +} + +impl Clone for FilePermissions { + fn clone(&self) -> FilePermissions { + self.0 + } +} + +impl PartialEq for FilePermissions { + fn eq(&self, _other: &FilePermissions) -> bool { + self.0 + } +} + +impl Eq for FilePermissions {} + +impl fmt::Debug for FilePermissions { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0 + } +} + +impl FileTimes { + pub fn set_accessed(&mut self, _t: SystemTime) {} + pub fn set_modified(&mut self, _t: SystemTime) {} +} + +impl FileType { + pub fn is_dir(&self) -> bool { + self.0 + } + + pub fn is_file(&self) -> bool { + self.0 + } + + pub fn is_symlink(&self) -> bool { + self.0 + } +} + +impl Clone for FileType { + fn clone(&self) -> FileType { + self.0 + } +} + +impl Copy for FileType {} + +impl PartialEq for FileType { + fn eq(&self, _other: &FileType) -> bool { + self.0 + } +} + +impl Eq for FileType {} + +impl Hash for FileType { + fn hash(&self, _h: &mut H) { + self.0 + } +} + +impl fmt::Debug for FileType { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0 + } +} + +impl fmt::Debug for ReadDir { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0 + } +} + +impl Iterator for ReadDir { + type Item = io::Result; + + fn next(&mut self) -> Option> { + self.0 + } +} + +impl DirEntry { + pub fn path(&self) -> PathBuf { + self.0 + } + + pub fn file_name(&self) -> OsString { + self.0 + } + + pub fn metadata(&self) -> io::Result { + self.0 + } + + pub fn file_type(&self) -> io::Result { + self.0 + } +} + +impl OpenOptions { + pub fn new() -> OpenOptions { + OpenOptions {} + } + + pub fn read(&mut self, _read: bool) {} + pub fn write(&mut self, _write: bool) {} + pub fn append(&mut self, _append: bool) {} + pub fn truncate(&mut self, _truncate: bool) {} + pub fn create(&mut self, _create: bool) {} + pub fn create_new(&mut self, _create_new: bool) {} +} + +impl File { + pub fn open(_path: &Path, _opts: &OpenOptions) -> io::Result { + unsupported() + } + + pub fn file_attr(&self) -> io::Result { + self.0 + } + + pub fn fsync(&self) -> io::Result<()> { + self.0 + } + + pub fn datasync(&self) -> io::Result<()> { + self.0 + } + + pub fn lock(&self) -> io::Result<()> { + self.0 + } + + pub fn lock_shared(&self) -> io::Result<()> { + self.0 + } + + pub fn try_lock(&self) -> io::Result { + self.0 + } + + pub fn try_lock_shared(&self) -> io::Result { + self.0 + } + + pub fn unlock(&self) -> io::Result<()> { + self.0 + } + + pub fn truncate(&self, _size: u64) -> io::Result<()> { + self.0 + } + + pub fn read(&self, _buf: &mut [u8]) -> io::Result { + self.0 + } + + pub fn read_vectored(&self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result { + self.0 + } + + pub fn is_read_vectored(&self) -> bool { + self.0 + } + + pub fn read_buf(&self, _cursor: BorrowedCursor<'_>) -> io::Result<()> { + self.0 + } + + pub fn write(&self, _buf: &[u8]) -> io::Result { + self.0 + } + + pub fn write_vectored(&self, _bufs: &[IoSlice<'_>]) -> io::Result { + self.0 + } + + pub fn is_write_vectored(&self) -> bool { + self.0 + } + + pub fn flush(&self) -> io::Result<()> { + self.0 + } + + pub fn seek(&self, _pos: SeekFrom) -> io::Result { + self.0 + } + + pub fn duplicate(&self) -> io::Result { + self.0 + } + + pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> { + self.0 + } + + pub fn set_times(&self, _times: FileTimes) -> io::Result<()> { + self.0 + } +} + +impl DirBuilder { + pub fn new() -> DirBuilder { + DirBuilder {} + } + + pub fn mkdir(&self, _p: &Path) -> io::Result<()> { + unsupported() + } +} + +impl fmt::Debug for File { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0 + } +} + +pub fn readdir(_p: &Path) -> io::Result { + unsupported() +} + +pub fn unlink(_p: &Path) -> io::Result<()> { + unsupported() +} + +pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> { + unsupported() +} + +pub fn set_perm(_p: &Path, perm: FilePermissions) -> io::Result<()> { + match perm.0 {} +} + +pub fn rmdir(_p: &Path) -> io::Result<()> { + unsupported() +} + +pub fn remove_dir_all(_path: &Path) -> io::Result<()> { + unsupported() +} + +pub fn exists(_path: &Path) -> io::Result { + unsupported() +} + +pub fn readlink(_p: &Path) -> io::Result { + unsupported() +} + +pub fn symlink(_original: &Path, _link: &Path) -> io::Result<()> { + unsupported() +} + +pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> { + unsupported() +} + +pub fn stat(_p: &Path) -> io::Result { + unsupported() +} + +pub fn lstat(_p: &Path) -> io::Result { + unsupported() +} + +pub fn canonicalize(_p: &Path) -> io::Result { + unsupported() +} + +pub fn copy(_from: &Path, _to: &Path) -> io::Result { + unsupported() +} diff --git a/std/src/sys/pal/uefi/helpers.rs b/std/src/sys/pal/uefi/helpers.rs index abc8e69a285f3..7504a0f7ad7f5 100644 --- a/std/src/sys/pal/uefi/helpers.rs +++ b/std/src/sys/pal/uefi/helpers.rs @@ -13,7 +13,7 @@ use r_efi::efi::{self, Guid}; use r_efi::protocols::{device_path, device_path_to_text, shell}; use crate::ffi::{OsStr, OsString}; -use crate::io::{self, const_io_error}; +use crate::io::{self, const_error}; use crate::mem::{MaybeUninit, size_of}; use crate::os::uefi::env::boot_services; use crate::os::uefi::ffi::{OsStrExt, OsStringExt}; @@ -30,7 +30,7 @@ type BootUninstallMultipleProtocolInterfaces = unsafe extern "efiapi" fn(_: r_efi::efi::Handle, _: ...) -> r_efi::efi::Status; const BOOT_SERVICES_UNAVAILABLE: io::Error = - const_io_error!(io::ErrorKind::Other, "Boot Services are no longer available"); + const_error!(io::ErrorKind::Other, "Boot Services are no longer available"); /// Locates Handles with a particular Protocol GUID. /// @@ -114,7 +114,7 @@ pub(crate) fn open_protocol( Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { NonNull::new(unsafe { protocol.assume_init() }) - .ok_or(const_io_error!(io::ErrorKind::Other, "null protocol")) + .ok_or(const_error!(io::ErrorKind::Other, "null protocol")) } } @@ -134,7 +134,7 @@ pub(crate) fn create_event( if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { - NonNull::new(event).ok_or(const_io_error!(io::ErrorKind::Other, "null protocol")) + NonNull::new(event).ok_or(const_error!(io::ErrorKind::Other, "null protocol")) } } @@ -155,10 +155,8 @@ pub(crate) unsafe fn close_event(evt: NonNull) -> io::Result /// /// Note: Some protocols need to be manually freed. It is the caller's responsibility to do so. pub(crate) fn image_handle_protocol(protocol_guid: Guid) -> io::Result> { - let system_handle = uefi::env::try_image_handle().ok_or(io::const_io_error!( - io::ErrorKind::NotFound, - "Protocol not found in Image handle" - ))?; + let system_handle = uefi::env::try_image_handle() + .ok_or(io::const_error!(io::ErrorKind::NotFound, "Protocol not found in Image handle"))?; open_protocol(system_handle, protocol_guid) } @@ -178,7 +176,7 @@ pub(crate) fn device_path_to_text(path: NonNull) -> io::R }; let path = os_string_from_raw(path_ptr) - .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))?; + .ok_or(io::const_error!(io::ErrorKind::InvalidData, "Invalid path"))?; if let Some(boot_services) = crate::os::uefi::env::boot_services() { let boot_services: NonNull = boot_services.cast(); @@ -213,7 +211,7 @@ pub(crate) fn device_path_to_text(path: NonNull) -> io::R } } - Err(io::const_io_error!(io::ErrorKind::NotFound, "No device path to text protocol found")) + Err(io::const_error!(io::ErrorKind::NotFound, "No device path to text protocol found")) } /// Gets RuntimeServices. @@ -224,17 +222,17 @@ pub(crate) fn runtime_services() -> Option> NonNull::new(runtime_services) } -pub(crate) struct DevicePath(NonNull); +pub(crate) struct OwnedDevicePath(NonNull); -impl DevicePath { +impl OwnedDevicePath { pub(crate) fn from_text(p: &OsStr) -> io::Result { fn inner( p: &OsStr, protocol: NonNull, - ) -> io::Result { + ) -> io::Result { let path_vec = p.encode_wide().chain(Some(0)).collect::>(); if path_vec[..path_vec.len() - 1].contains(&0) { - return Err(const_io_error!( + return Err(const_error!( io::ErrorKind::InvalidInput, "strings passed to UEFI cannot contain NULs", )); @@ -243,9 +241,9 @@ impl DevicePath { let path = unsafe { ((*protocol.as_ptr()).convert_text_to_device_path)(path_vec.as_ptr()) }; - NonNull::new(path).map(DevicePath).ok_or_else(|| { - const_io_error!(io::ErrorKind::InvalidFilename, "Invalid Device Path") - }) + NonNull::new(path) + .map(OwnedDevicePath) + .ok_or_else(|| const_error!(io::ErrorKind::InvalidFilename, "Invalid Device Path")) } static LAST_VALID_HANDLE: AtomicPtr = @@ -271,18 +269,18 @@ impl DevicePath { } } - io::Result::Err(const_io_error!( + io::Result::Err(const_error!( io::ErrorKind::NotFound, "DevicePathFromText Protocol not found" )) } - pub(crate) fn as_ptr(&self) -> *mut r_efi::protocols::device_path::Protocol { + pub(crate) const fn as_ptr(&self) -> *mut r_efi::protocols::device_path::Protocol { self.0.as_ptr() } } -impl Drop for DevicePath { +impl Drop for OwnedDevicePath { fn drop(&mut self) { if let Some(bt) = boot_services() { let bt: NonNull = bt.cast(); @@ -293,6 +291,15 @@ impl Drop for DevicePath { } } +impl crate::fmt::Debug for OwnedDevicePath { + fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result { + match device_path_to_text(self.0) { + Ok(p) => p.fmt(f), + Err(_) => f.debug_struct("OwnedDevicePath").finish_non_exhaustive(), + } + } +} + pub(crate) struct OwnedProtocol { guid: r_efi::efi::Guid, handle: NonNull, @@ -326,7 +333,7 @@ impl OwnedProtocol { }; let handle = NonNull::new(handle) - .ok_or(io::const_io_error!(io::ErrorKind::Uncategorized, "found null handle"))?; + .ok_or(io::const_error!(io::ErrorKind::Uncategorized, "found null handle"))?; Ok(Self { guid, handle, protocol }) } diff --git a/std/src/sys/pal/uefi/mod.rs b/std/src/sys/pal/uefi/mod.rs index c0ab52f650aa5..111bed7a7eb64 100644 --- a/std/src/sys/pal/uefi/mod.rs +++ b/std/src/sys/pal/uefi/mod.rs @@ -15,7 +15,6 @@ pub mod args; pub mod env; -#[path = "../unsupported/fs.rs"] pub mod fs; pub mod helpers; #[path = "../unsupported/io.rs"] @@ -95,7 +94,7 @@ pub const fn unsupported() -> std_io::Result { #[inline] pub const fn unsupported_err() -> std_io::Error { - std_io::const_io_error!(std_io::ErrorKind::Unsupported, "operation not supported on UEFI",) + std_io::const_error!(std_io::ErrorKind::Unsupported, "operation not supported on UEFI",) } pub fn decode_error_kind(code: RawOsError) -> crate::io::ErrorKind { diff --git a/std/src/sys/pal/uefi/os.rs b/std/src/sys/pal/uefi/os.rs index 27395f7c3c0b3..6d23c72ef2209 100644 --- a/std/src/sys/pal/uefi/os.rs +++ b/std/src/sys/pal/uefi/os.rs @@ -131,7 +131,7 @@ pub fn getcwd() -> io::Result { let path_ptr = unsafe { ((*shell.as_ptr()).get_cur_dir)(crate::ptr::null_mut()) }; helpers::os_string_from_raw(path_ptr) .map(PathBuf::from) - .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path")) + .ok_or(io::const_error!(io::ErrorKind::InvalidData, "Invalid path")) } None => { let mut t = current_exe()?; @@ -147,7 +147,7 @@ pub fn chdir(p: &path::Path) -> io::Result<()> { let shell = helpers::open_shell().ok_or(unsupported_err())?; let mut p = helpers::os_string_to_raw(p.as_os_str()) - .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))?; + .ok_or(io::const_error!(io::ErrorKind::InvalidData, "Invalid path"))?; let r = unsafe { ((*shell.as_ptr()).set_cur_dir)(crate::ptr::null_mut(), p.as_mut_ptr()) }; if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } @@ -290,15 +290,15 @@ mod uefi_env { pub(crate) fn set(key: &OsStr, val: &OsStr) -> io::Result<()> { let mut key_ptr = helpers::os_string_to_raw(key) - .ok_or(io::const_io_error!(io::ErrorKind::InvalidInput, "Invalid Key"))?; + .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "Invalid Key"))?; let mut val_ptr = helpers::os_string_to_raw(val) - .ok_or(io::const_io_error!(io::ErrorKind::InvalidInput, "Invalid Value"))?; + .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "Invalid Value"))?; unsafe { set_raw(key_ptr.as_mut_ptr(), val_ptr.as_mut_ptr()) } } pub(crate) fn unset(key: &OsStr) -> io::Result<()> { let mut key_ptr = helpers::os_string_to_raw(key) - .ok_or(io::const_io_error!(io::ErrorKind::InvalidInput, "Invalid Key"))?; + .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "Invalid Key"))?; unsafe { set_raw(key_ptr.as_mut_ptr(), crate::ptr::null_mut()) } } @@ -328,7 +328,7 @@ mod uefi_env { }); // SAFETY: val.add(start) is always NULL terminated let val = unsafe { get_raw(shell, val.add(start)) } - .ok_or(io::const_io_error!(io::ErrorKind::InvalidInput, "Invalid Value"))?; + .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "Invalid Value"))?; vars.push((key, val)); start = i + 1; diff --git a/std/src/sys/pal/uefi/process.rs b/std/src/sys/pal/uefi/process.rs index 1b83f4b0aee88..1a0754134dfb8 100644 --- a/std/src/sys/pal/uefi/process.rs +++ b/std/src/sys/pal/uefi/process.rs @@ -307,7 +307,7 @@ mod uefi_command_internal { use super::super::helpers; use crate::ffi::{OsStr, OsString}; - use crate::io::{self, const_io_error}; + use crate::io::{self, const_error}; use crate::mem::MaybeUninit; use crate::os::uefi::env::{boot_services, image_handle, system_table}; use crate::os::uefi::ffi::{OsStrExt, OsStringExt}; @@ -326,9 +326,9 @@ mod uefi_command_internal { impl Image { pub fn load_image(p: &OsStr) -> io::Result { - let path = helpers::DevicePath::from_text(p)?; + let path = helpers::OwnedDevicePath::from_text(p)?; let boot_services: NonNull = boot_services() - .ok_or_else(|| const_io_error!(io::ErrorKind::NotFound, "Boot Services not found"))? + .ok_or_else(|| const_error!(io::ErrorKind::NotFound, "Boot Services not found"))? .cast(); let mut child_handle: MaybeUninit = MaybeUninit::uninit(); let image_handle = image_handle(); @@ -369,7 +369,7 @@ mod uefi_command_internal { } let boot_services: NonNull = boot_services() - .ok_or_else(|| const_io_error!(io::ErrorKind::NotFound, "Boot Services not found"))? + .ok_or_else(|| const_error!(io::ErrorKind::NotFound, "Boot Services not found"))? .cast(); let mut exit_data_size: usize = 0; let mut exit_data: MaybeUninit<*mut u16> = MaybeUninit::uninit(); @@ -583,7 +583,7 @@ mod uefi_command_internal { OsString::from_wide(&self._buffer) .into_string() .map(Into::into) - .map_err(|_| const_io_error!(io::ErrorKind::Other, "utf8 conversion failed")) + .map_err(|_| const_error!(io::ErrorKind::Other, "utf8 conversion failed")) } extern "efiapi" fn reset( diff --git a/std/src/sys/pal/unix/fd.rs b/std/src/sys/pal/unix/fd.rs index 6a28799ca55eb..2fc33bdfefbf5 100644 --- a/std/src/sys/pal/unix/fd.rs +++ b/std/src/sys/pal/unix/fd.rs @@ -5,7 +5,6 @@ mod tests; #[cfg(not(any( target_os = "linux", - target_os = "emscripten", target_os = "l4re", target_os = "android", target_os = "hurd", @@ -14,7 +13,6 @@ use libc::off_t as off64_t; #[cfg(any( target_os = "android", target_os = "linux", - target_os = "emscripten", target_os = "l4re", target_os = "hurd", ))] diff --git a/std/src/sys/pal/unix/fs.rs b/std/src/sys/pal/unix/fs.rs index 96f99efb21e84..fdf011c19482a 100644 --- a/std/src/sys/pal/unix/fs.rs +++ b/std/src/sys/pal/unix/fs.rs @@ -8,16 +8,11 @@ mod tests; use libc::c_char; #[cfg(any( all(target_os = "linux", not(target_env = "musl")), - target_os = "emscripten", target_os = "android", target_os = "hurd" ))] use libc::dirfd; -#[cfg(any( - all(target_os = "linux", not(target_env = "musl")), - target_os = "emscripten", - target_os = "hurd" -))] +#[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "hurd"))] use libc::fstatat64; #[cfg(any( target_os = "android", @@ -34,7 +29,6 @@ use libc::readdir as readdir64; #[cfg(not(any( target_os = "android", target_os = "linux", - target_os = "emscripten", target_os = "solaris", target_os = "illumos", target_os = "l4re", @@ -48,7 +42,7 @@ use libc::readdir as readdir64; use libc::readdir_r as readdir64_r; #[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "hurd"))] use libc::readdir64; -#[cfg(any(target_os = "emscripten", target_os = "l4re"))] +#[cfg(target_os = "l4re")] use libc::readdir64_r; use libc::{c_int, mode_t}; #[cfg(target_os = "android")] @@ -58,7 +52,6 @@ use libc::{ }; #[cfg(not(any( all(target_os = "linux", not(target_env = "musl")), - target_os = "emscripten", target_os = "l4re", target_os = "android", target_os = "hurd", @@ -69,7 +62,6 @@ use libc::{ }; #[cfg(any( all(target_os = "linux", not(target_env = "musl")), - target_os = "emscripten", target_os = "l4re", target_os = "hurd" ))] @@ -168,7 +160,8 @@ cfg_has_statx! {{ ) -> c_int } - if STATX_SAVED_STATE.load(Ordering::Relaxed) == STATX_STATE::Unavailable as u8 { + let statx_availability = STATX_SAVED_STATE.load(Ordering::Relaxed); + if statx_availability == STATX_STATE::Unavailable as u8 { return None; } @@ -200,6 +193,9 @@ cfg_has_statx! {{ return None; } } + if statx_availability == STATX_STATE::Unknown as u8 { + STATX_SAVED_STATE.store(STATX_STATE::Present as u8, Ordering::Relaxed); + } // We cannot fill `stat64` exhaustively because of private padding fields. let mut stat: stat64 = mem::zeroed(); @@ -559,7 +555,7 @@ impl FileAttr { return if (ext.stx_mask & libc::STATX_BTIME) != 0 { SystemTime::new(ext.stx_btime.tv_sec, ext.stx_btime.tv_nsec as i64) } else { - Err(io::const_io_error!( + Err(io::const_error!( io::ErrorKind::Unsupported, "creation time is not available for the filesystem", )) @@ -567,7 +563,7 @@ impl FileAttr { } } - Err(io::const_io_error!( + Err(io::const_error!( io::ErrorKind::Unsupported, "creation time is not available on this platform \ currently", @@ -713,7 +709,7 @@ impl Iterator for ReadDir { // thread safety for readdir() as long an individual DIR* is not accessed // concurrently, which is sufficient for Rust. super::os::set_errno(0); - let entry_ptr = readdir64(self.inner.dirp.0); + let entry_ptr: *const dirent64 = readdir64(self.inner.dirp.0); if entry_ptr.is_null() { // We either encountered an error, or reached the end. Either way, // the next call to next() should return None. @@ -739,29 +735,19 @@ impl Iterator for ReadDir { // contents were "simply" partially initialized data. // // Like for uninitialized contents, converting entry_ptr to `&dirent64` - // would not be legal. However, unique to dirent64 is that we don't even - // get to use `&raw const (*entry_ptr).d_name` because that operation - // requires the full extent of *entry_ptr to be in bounds of the same - // allocation, which is not necessarily the case here. - // - // Instead we must access fields individually through their offsets. - macro_rules! offset_ptr { - ($entry_ptr:expr, $field:ident) => {{ - const OFFSET: isize = mem::offset_of!(dirent64, $field) as isize; - if true { - // Cast to the same type determined by the else branch. - $entry_ptr.byte_offset(OFFSET).cast::<_>() - } else { - #[allow(deref_nullptr)] - { - &raw const (*ptr::null::()).$field - } - } - }}; + // would not be legal. However, we can use `&raw const (*entry_ptr).d_name` + // to refer the fields individually, because that operation is equivalent + // to `byte_offset` and thus does not require the full extent of `*entry_ptr` + // to be in bounds of the same allocation, only the offset of the field + // being referenced. + macro_rules! entry_field_ptr { + ($field:ident) => { + &raw const (*entry_ptr).$field + }; } // d_name is guaranteed to be null-terminated. - let name = CStr::from_ptr(offset_ptr!(entry_ptr, d_name).cast()); + let name = CStr::from_ptr(entry_field_ptr!(d_name).cast()); let name_bytes = name.to_bytes(); if name_bytes == b"." || name_bytes == b".." { continue; @@ -769,14 +755,14 @@ impl Iterator for ReadDir { #[cfg(not(target_os = "vita"))] let entry = dirent64_min { - d_ino: *offset_ptr!(entry_ptr, d_ino) as u64, + d_ino: *entry_field_ptr!(d_ino) as u64, #[cfg(not(any( target_os = "solaris", target_os = "illumos", target_os = "aix", target_os = "nto", )))] - d_type: *offset_ptr!(entry_ptr, d_type) as u8, + d_type: *entry_field_ptr!(d_type) as u8, }; #[cfg(target_os = "vita")] @@ -895,7 +881,6 @@ impl DirEntry { #[cfg(all( any( all(target_os = "linux", not(target_env = "musl")), - target_os = "emscripten", target_os = "android", target_os = "hurd" ), @@ -924,7 +909,6 @@ impl DirEntry { #[cfg(any( not(any( all(target_os = "linux", not(target_env = "musl")), - target_os = "emscripten", target_os = "android", target_os = "hurd", )), @@ -1272,7 +1256,7 @@ impl File { target_vendor = "apple", )))] pub fn lock(&self) -> io::Result<()> { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "lock() not supported")) + Err(io::const_error!(io::ErrorKind::Unsupported, "lock() not supported")) } #[cfg(any( @@ -1293,7 +1277,7 @@ impl File { target_vendor = "apple", )))] pub fn lock_shared(&self) -> io::Result<()> { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "lock_shared() not supported")) + Err(io::const_error!(io::ErrorKind::Unsupported, "lock_shared() not supported")) } #[cfg(any( @@ -1320,7 +1304,7 @@ impl File { target_vendor = "apple", )))] pub fn try_lock(&self) -> io::Result { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "try_lock() not supported")) + Err(io::const_error!(io::ErrorKind::Unsupported, "try_lock() not supported")) } #[cfg(any( @@ -1347,7 +1331,7 @@ impl File { target_vendor = "apple", )))] pub fn try_lock_shared(&self) -> io::Result { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "try_lock_shared() not supported")) + Err(io::const_error!(io::ErrorKind::Unsupported, "try_lock_shared() not supported")) } #[cfg(any( @@ -1368,7 +1352,7 @@ impl File { target_vendor = "apple", )))] pub fn unlock(&self) -> io::Result<()> { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "unlock() not supported")) + Err(io::const_error!(io::ErrorKind::Unsupported, "unlock() not supported")) } pub fn truncate(&self, size: u64) -> io::Result<()> { @@ -1459,11 +1443,11 @@ impl File { )))] let to_timespec = |time: Option| match time { Some(time) if let Some(ts) = time.t.to_timespec() => Ok(ts), - Some(time) if time > crate::sys::time::UNIX_EPOCH => Err(io::const_io_error!( + Some(time) if time > crate::sys::time::UNIX_EPOCH => Err(io::const_error!( io::ErrorKind::InvalidInput, "timestamp is too large to set as a file time" )), - Some(_) => Err(io::const_io_error!( + Some(_) => Err(io::const_error!( io::ErrorKind::InvalidInput, "timestamp is too small to set as a file time" )), @@ -1476,7 +1460,7 @@ impl File { // the same as for Redox. // `futimens` and `UTIME_OMIT` are a work in progress for vxworks. let _ = times; - Err(io::const_io_error!( + Err(io::const_error!( io::ErrorKind::Unsupported, "setting file times not supported", )) @@ -1515,7 +1499,7 @@ impl File { weak!(fn futimens(c_int, *const libc::timespec) -> c_int); match futimens.get() { Some(futimens) => futimens(self.as_raw_fd(), times.as_ptr()), - None => return Err(io::const_io_error!( + None => return Err(io::const_error!( io::ErrorKind::Unsupported, "setting file times requires Android API level >= 19", )), @@ -1944,7 +1928,7 @@ fn open_from(from: &Path) -> io::Result<(crate::fs::File, crate::fs::Metadata)> #[cfg(target_os = "espidf")] fn open_to_and_set_permissions( to: &Path, - _reader_metadata: crate::fs::Metadata, + _reader_metadata: &crate::fs::Metadata, ) -> io::Result<(crate::fs::File, crate::fs::Metadata)> { use crate::fs::OpenOptions; let writer = OpenOptions::new().open(to)?; @@ -1955,7 +1939,7 @@ fn open_to_and_set_permissions( #[cfg(not(target_os = "espidf"))] fn open_to_and_set_permissions( to: &Path, - reader_metadata: crate::fs::Metadata, + reader_metadata: &crate::fs::Metadata, ) -> io::Result<(crate::fs::File, crate::fs::Metadata)> { use crate::fs::OpenOptions; use crate::os::unix::fs::{OpenOptionsExt, PermissionsExt}; @@ -1980,30 +1964,63 @@ fn open_to_and_set_permissions( Ok((writer, writer_metadata)) } -#[cfg(not(any(target_os = "linux", target_os = "android", target_vendor = "apple")))] -pub fn copy(from: &Path, to: &Path) -> io::Result { - let (mut reader, reader_metadata) = open_from(from)?; - let (mut writer, _) = open_to_and_set_permissions(to, reader_metadata)?; +mod cfm { + use crate::fs::{File, Metadata}; + use crate::io::{BorrowedCursor, IoSlice, IoSliceMut, Read, Result, Write}; - io::copy(&mut reader, &mut writer) -} + #[allow(dead_code)] + pub struct CachedFileMetadata(pub File, pub Metadata); + impl Read for CachedFileMetadata { + fn read(&mut self, buf: &mut [u8]) -> Result { + self.0.read(buf) + } + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result { + self.0.read_vectored(bufs) + } + fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> Result<()> { + self.0.read_buf(cursor) + } + #[inline] + fn is_read_vectored(&self) -> bool { + self.0.is_read_vectored() + } + fn read_to_end(&mut self, buf: &mut Vec) -> Result { + self.0.read_to_end(buf) + } + fn read_to_string(&mut self, buf: &mut String) -> Result { + self.0.read_to_string(buf) + } + } + impl Write for CachedFileMetadata { + fn write(&mut self, buf: &[u8]) -> Result { + self.0.write(buf) + } + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result { + self.0.write_vectored(bufs) + } + #[inline] + fn is_write_vectored(&self) -> bool { + self.0.is_write_vectored() + } + #[inline] + fn flush(&mut self) -> Result<()> { + self.0.flush() + } + } +} #[cfg(any(target_os = "linux", target_os = "android"))] +pub(crate) use cfm::CachedFileMetadata; + +#[cfg(not(target_vendor = "apple"))] pub fn copy(from: &Path, to: &Path) -> io::Result { - let (mut reader, reader_metadata) = open_from(from)?; - let max_len = u64::MAX; - let (mut writer, _) = open_to_and_set_permissions(to, reader_metadata)?; - - use super::kernel_copy::{CopyResult, copy_regular_files}; - - match copy_regular_files(reader.as_raw_fd(), writer.as_raw_fd(), max_len) { - CopyResult::Ended(bytes) => Ok(bytes), - CopyResult::Error(e, _) => Err(e), - CopyResult::Fallback(written) => match io::copy::generic_copy(&mut reader, &mut writer) { - Ok(bytes) => Ok(bytes + written), - Err(e) => Err(e), - }, - } + let (reader, reader_metadata) = open_from(from)?; + let (writer, writer_metadata) = open_to_and_set_permissions(to, &reader_metadata)?; + + io::copy( + &mut cfm::CachedFileMetadata(reader, reader_metadata), + &mut cfm::CachedFileMetadata(writer, writer_metadata), + ) } #[cfg(target_vendor = "apple")] @@ -2040,7 +2057,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { } // Fall back to using `fcopyfile` if `fclonefileat` does not succeed. - let (writer, writer_metadata) = open_to_and_set_permissions(to, reader_metadata)?; + let (writer, writer_metadata) = open_to_and_set_permissions(to, &reader_metadata)?; // We ensure that `FreeOnDrop` never contains a null pointer so it is // always safe to call `copyfile_state_free` @@ -2090,7 +2107,7 @@ pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> { #[cfg(target_os = "vxworks")] pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> { let (_, _, _) = (path, uid, gid); - Err(io::const_io_error!(io::ErrorKind::Unsupported, "lchown not supported by vxworks")) + Err(io::const_error!(io::ErrorKind::Unsupported, "lchown not supported by vxworks")) } #[cfg(not(any(target_os = "fuchsia", target_os = "vxworks")))] @@ -2101,7 +2118,7 @@ pub fn chroot(dir: &Path) -> io::Result<()> { #[cfg(target_os = "vxworks")] pub fn chroot(dir: &Path) -> io::Result<()> { let _ = dir; - Err(io::const_io_error!(io::ErrorKind::Unsupported, "chroot not supported by vxworks")) + Err(io::const_error!(io::ErrorKind::Unsupported, "chroot not supported by vxworks")) } pub use remove_dir_impl::remove_dir_all; diff --git a/std/src/sys/pal/unix/kernel_copy.rs b/std/src/sys/pal/unix/kernel_copy.rs index a671383cb7957..36823a503b17c 100644 --- a/std/src/sys/pal/unix/kernel_copy.rs +++ b/std/src/sys/pal/unix/kernel_copy.rs @@ -65,6 +65,7 @@ use crate::process::{ChildStderr, ChildStdin, ChildStdout}; use crate::ptr; use crate::sync::atomic::{AtomicBool, AtomicU8, Ordering}; use crate::sys::cvt; +use crate::sys::fs::CachedFileMetadata; use crate::sys::weak::syscall; #[cfg(test)] @@ -192,7 +193,7 @@ impl SpecCopy for Copier<'_, '_, R, W> { let w_cfg = writer.properties(); // before direct operations on file descriptors ensure that all source and sink buffers are empty - let mut flush = || -> crate::io::Result { + let mut flush = || -> Result { let bytes = reader.drain_to(writer, u64::MAX)?; // BufWriter buffered bytes have already been accounted for in earlier write() calls writer.flush()?; @@ -537,6 +538,18 @@ impl CopyWrite for BufWriter { } } +impl CopyRead for CachedFileMetadata { + fn properties(&self) -> CopyParams { + CopyParams(FdMeta::Metadata(self.1.clone()), Some(self.0.as_raw_fd())) + } +} + +impl CopyWrite for CachedFileMetadata { + fn properties(&self) -> CopyParams { + CopyParams(FdMeta::Metadata(self.1.clone()), Some(self.0.as_raw_fd())) + } +} + fn fd_to_meta(fd: &T) -> FdMeta { let fd = fd.as_raw_fd(); let file: ManuallyDrop = ManuallyDrop::new(unsafe { File::from_raw_fd(fd) }); diff --git a/std/src/sys/pal/unix/l4re.rs b/std/src/sys/pal/unix/l4re.rs index 52d39dcfb16fb..37dd370c5146c 100644 --- a/std/src/sys/pal/unix/l4re.rs +++ b/std/src/sys/pal/unix/l4re.rs @@ -1,6 +1,6 @@ macro_rules! unimpl { () => { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Unsupported, "No networking available on L4Re.", )); diff --git a/std/src/sys/pal/unix/mod.rs b/std/src/sys/pal/unix/mod.rs index 4fe18daa2040f..3cc1cae8d000e 100644 --- a/std/src/sys/pal/unix/mod.rs +++ b/std/src/sys/pal/unix/mod.rs @@ -27,6 +27,7 @@ pub mod pipe; pub mod process; pub mod stack_overflow; pub mod stdio; +pub mod sync; pub mod thread; pub mod thread_parking; pub mod time; @@ -253,7 +254,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind { libc::ECONNREFUSED => ConnectionRefused, libc::ECONNRESET => ConnectionReset, libc::EDEADLK => Deadlock, - libc::EDQUOT => FilesystemQuotaExceeded, + libc::EDQUOT => QuotaExceeded, libc::EEXIST => AlreadyExists, libc::EFBIG => FileTooLarge, libc::EHOSTUNREACH => HostUnreachable, diff --git a/std/src/sys/pal/unix/net.rs b/std/src/sys/pal/unix/net.rs index 6a67bb0a101e9..d73b9fd5eb882 100644 --- a/std/src/sys/pal/unix/net.rs +++ b/std/src/sys/pal/unix/net.rs @@ -81,6 +81,7 @@ impl Socket { target_os = "netbsd", target_os = "openbsd", target_os = "nto", + target_os = "solaris", ))] { // On platforms that support it we pass the SOCK_CLOEXEC // flag to atomically create the socket and set it as @@ -190,7 +191,7 @@ impl Socket { loop { let elapsed = start.elapsed(); if elapsed >= timeout { - return Err(io::const_io_error!(io::ErrorKind::TimedOut, "connection timed out")); + return Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out")); } let timeout = timeout - elapsed; @@ -225,7 +226,7 @@ impl Socket { // for POLLHUP or POLLERR rather than read readiness if pollfd.revents & (libc::POLLHUP | libc::POLLERR) != 0 { let e = self.take_error()?.unwrap_or_else(|| { - io::const_io_error!( + io::const_error!( io::ErrorKind::Uncategorized, "no error set after POLLHUP", ) diff --git a/std/src/sys/pal/unix/os.rs b/std/src/sys/pal/unix/os.rs index f207131ddf332..b83772e34c173 100644 --- a/std/src/sys/pal/unix/os.rs +++ b/std/src/sys/pal/unix/os.rs @@ -258,7 +258,7 @@ pub fn current_exe() -> io::Result { use crate::env; use crate::io::ErrorKind; - let exe_path = env::args().next().ok_or(io::const_io_error!( + let exe_path = env::args().next().ok_or(io::const_error!( ErrorKind::NotFound, "an executable path was not found because no arguments were provided through argv" ))?; @@ -284,7 +284,7 @@ pub fn current_exe() -> io::Result { } } } - Err(io::const_io_error!(ErrorKind::NotFound, "an executable path was not found")) + Err(io::const_error!(ErrorKind::NotFound, "an executable path was not found")) } #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] @@ -340,7 +340,7 @@ pub fn current_exe() -> io::Result { 0, ))?; if path_len <= 1 { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Uncategorized, "KERN_PROC_PATHNAME sysctl returned zero-length string", )); @@ -363,7 +363,7 @@ pub fn current_exe() -> io::Result { if curproc_exe.is_file() { return crate::fs::read_link(curproc_exe); } - Err(io::const_io_error!( + Err(io::const_error!( io::ErrorKind::Uncategorized, "/proc/curproc/exe doesn't point to regular file.", )) @@ -382,10 +382,9 @@ pub fn current_exe() -> io::Result { cvt(libc::sysctl(mib, 4, argv.as_mut_ptr() as *mut _, &mut argv_len, ptr::null_mut(), 0))?; argv.set_len(argv_len as usize); if argv[0].is_null() { - return Err(io::const_io_error!( - io::ErrorKind::Uncategorized, - "no current exe available", - )); + return Err( + io::const_error!(io::ErrorKind::Uncategorized, "no current exe available",), + ); } let argv0 = CStr::from_ptr(argv[0]).to_bytes(); if argv0[0] == b'.' || argv0.iter().any(|b| *b == b'/') { @@ -405,7 +404,7 @@ pub fn current_exe() -> io::Result { ))] pub fn current_exe() -> io::Result { match crate::fs::read_link("/proc/self/exe") { - Err(ref e) if e.kind() == io::ErrorKind::NotFound => Err(io::const_io_error!( + Err(ref e) if e.kind() == io::ErrorKind::NotFound => Err(io::const_error!( io::ErrorKind::Uncategorized, "no /proc/self/exe available. Is /proc mounted?", )), @@ -428,11 +427,13 @@ pub fn current_exe() -> io::Result { pub fn current_exe() -> io::Result { unsafe { let mut sz: u32 = 0; + #[expect(deprecated)] libc::_NSGetExecutablePath(ptr::null_mut(), &mut sz); if sz == 0 { return Err(io::Error::last_os_error()); } let mut v: Vec = Vec::with_capacity(sz as usize); + #[expect(deprecated)] let err = libc::_NSGetExecutablePath(v.as_mut_ptr() as *mut i8, &mut sz); if err != 0 { return Err(io::Error::last_os_error()); @@ -476,7 +477,7 @@ pub fn current_exe() -> io::Result { ); if result != libc::B_OK { use crate::io::ErrorKind; - Err(io::const_io_error!(ErrorKind::Uncategorized, "Error getting executable path")) + Err(io::const_error!(ErrorKind::Uncategorized, "Error getting executable path")) } else { // find_path adds the null terminator. let name = CStr::from_ptr(name.as_ptr()).to_bytes(); @@ -493,7 +494,7 @@ pub fn current_exe() -> io::Result { #[cfg(target_os = "l4re")] pub fn current_exe() -> io::Result { use crate::io::ErrorKind; - Err(io::const_io_error!(ErrorKind::Unsupported, "Not yet implemented!")) + Err(io::const_error!(ErrorKind::Unsupported, "Not yet implemented!")) } #[cfg(target_os = "vxworks")] @@ -523,7 +524,7 @@ pub fn current_exe() -> io::Result { use crate::env; use crate::io::ErrorKind; - let exe_path = env::args().next().ok_or(io::const_io_error!( + let exe_path = env::args().next().ok_or(io::const_error!( ErrorKind::Uncategorized, "an executable path was not found because no arguments were provided through argv" ))?; diff --git a/std/src/sys/pal/unix/process/process_common.rs b/std/src/sys/pal/unix/process/process_common.rs index 13290fed762ae..342818ac91183 100644 --- a/std/src/sys/pal/unix/process/process_common.rs +++ b/std/src/sys/pal/unix/process/process_common.rs @@ -393,7 +393,7 @@ impl Command { fn os2c(s: &OsStr, saw_nul: &mut bool) -> CString { CString::new(s.as_bytes()).unwrap_or_else(|_e| { *saw_nul = true; - CString::new("").unwrap() + c"".to_owned() }) } diff --git a/std/src/sys/pal/unix/process/process_fuchsia.rs b/std/src/sys/pal/unix/process/process_fuchsia.rs index 8f7d786e32fcd..b7a35718757ae 100644 --- a/std/src/sys/pal/unix/process/process_fuchsia.rs +++ b/std/src/sys/pal/unix/process/process_fuchsia.rs @@ -18,7 +18,7 @@ impl Command { let envp = self.capture_env(); if self.saw_nul() { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "nul byte found in provided data", )); @@ -38,7 +38,7 @@ impl Command { pub fn exec(&mut self, default: Stdio) -> io::Error { if self.saw_nul() { - return io::const_io_error!( + return io::const_error!( io::ErrorKind::InvalidInput, "nul byte found in provided data", ); @@ -185,7 +185,7 @@ impl Process { ))?; } if actual != 1 { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidData, "Failed to get exit status of process", )); @@ -222,7 +222,7 @@ impl Process { ))?; } if actual != 1 { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidData, "Failed to get exit status of process", )); diff --git a/std/src/sys/pal/unix/process/process_unix.rs b/std/src/sys/pal/unix/process/process_unix.rs index 8faf1fda5464d..ec4965c1d7196 100644 --- a/std/src/sys/pal/unix/process/process_unix.rs +++ b/std/src/sys/pal/unix/process/process_unix.rs @@ -61,7 +61,7 @@ impl Command { let envp = self.capture_env(); if self.saw_nul() { - return Err(io::const_io_error!( + return Err(io::const_error!( ErrorKind::InvalidInput, "nul byte found in provided data", )); @@ -175,7 +175,7 @@ impl Command { // allowed to exist in dead code), but it sounds bad, so we go out of our // way to avoid that all-together. #[cfg(any(target_os = "tvos", target_os = "watchos"))] - const ERR_APPLE_TV_WATCH_NO_FORK_EXEC: Error = io::const_io_error!( + const ERR_APPLE_TV_WATCH_NO_FORK_EXEC: Error = io::const_error!( ErrorKind::Unsupported, "`fork`+`exec`-based process spawning is not supported on this target", ); @@ -218,7 +218,7 @@ impl Command { } else if delay < MAX_FORKSPAWN_SLEEP { thread::sleep(delay); } else { - return Err(io::const_io_error!( + return Err(io::const_error!( ErrorKind::WouldBlock, "forking returned EBADF too often", )); @@ -235,7 +235,7 @@ impl Command { let envp = self.capture_env(); if self.saw_nul() { - return io::const_io_error!(ErrorKind::InvalidInput, "nul byte found in provided data",); + return io::const_error!(ErrorKind::InvalidInput, "nul byte found in provided data",); } match self.setup_io(default, true) { @@ -561,7 +561,7 @@ impl Command { } else if delay < MAX_FORKSPAWN_SLEEP { thread::sleep(delay); } else { - return Err(io::const_io_error!( + return Err(io::const_error!( ErrorKind::WouldBlock, "posix_spawnp returned EBADF too often", )); diff --git a/std/src/sys/pal/unix/process/process_vxworks.rs b/std/src/sys/pal/unix/process/process_vxworks.rs index 38daf6af91808..e2c1b6a032624 100644 --- a/std/src/sys/pal/unix/process/process_vxworks.rs +++ b/std/src/sys/pal/unix/process/process_vxworks.rs @@ -22,7 +22,7 @@ impl Command { let envp = self.capture_env(); if self.saw_nul() { - return Err(io::const_io_error!( + return Err(io::const_error!( ErrorKind::InvalidInput, "nul byte found in provided data", )); diff --git a/std/src/sys/pal/unix/stack_overflow.rs b/std/src/sys/pal/unix/stack_overflow.rs index 69b31da427fcb..db5c6bd3a1c32 100644 --- a/std/src/sys/pal/unix/stack_overflow.rs +++ b/std/src/sys/pal/unix/stack_overflow.rs @@ -100,10 +100,11 @@ mod imp { // If the faulting address is within the guard page, then we print a // message saying so and abort. if start <= addr && addr < end { - rtprintpanic!( - "\nthread '{}' has overflowed its stack\n", - thread::current().name().unwrap_or("") - ); + thread::with_current_name(|name| { + let name = name.unwrap_or(""); + rtprintpanic!("\nthread '{name}' has overflowed its stack\n"); + }); + rtabort!("stack overflow"); } else { // Unregister ourselves by reverting back to the default behavior. diff --git a/std/src/sys/pal/unix/sync/condvar.rs b/std/src/sys/pal/unix/sync/condvar.rs new file mode 100644 index 0000000000000..73631053e9f47 --- /dev/null +++ b/std/src/sys/pal/unix/sync/condvar.rs @@ -0,0 +1,172 @@ +use super::Mutex; +use crate::cell::UnsafeCell; +use crate::pin::Pin; +#[cfg(not(target_os = "nto"))] +use crate::sys::pal::time::TIMESPEC_MAX; +#[cfg(target_os = "nto")] +use crate::sys::pal::time::TIMESPEC_MAX_CAPPED; +use crate::sys::pal::time::Timespec; +use crate::time::Duration; + +pub struct Condvar { + inner: UnsafeCell, +} + +impl Condvar { + pub fn new() -> Condvar { + Condvar { inner: UnsafeCell::new(libc::PTHREAD_COND_INITIALIZER) } + } + + #[inline] + fn raw(&self) -> *mut libc::pthread_cond_t { + self.inner.get() + } + + /// # Safety + /// `init` must have been called on this instance. + #[inline] + pub unsafe fn notify_one(self: Pin<&Self>) { + let r = unsafe { libc::pthread_cond_signal(self.raw()) }; + debug_assert_eq!(r, 0); + } + + /// # Safety + /// `init` must have been called on this instance. + #[inline] + pub unsafe fn notify_all(self: Pin<&Self>) { + let r = unsafe { libc::pthread_cond_broadcast(self.raw()) }; + debug_assert_eq!(r, 0); + } + + /// # Safety + /// * `init` must have been called on this instance. + /// * `mutex` must be locked by the current thread. + /// * This condition variable may only be used with the same mutex. + #[inline] + pub unsafe fn wait(self: Pin<&Self>, mutex: Pin<&Mutex>) { + let r = unsafe { libc::pthread_cond_wait(self.raw(), mutex.raw()) }; + debug_assert_eq!(r, 0); + } + + /// # Safety + /// * `init` must have been called on this instance. + /// * `mutex` must be locked by the current thread. + /// * This condition variable may only be used with the same mutex. + pub unsafe fn wait_timeout(&self, mutex: Pin<&Mutex>, dur: Duration) -> bool { + let mutex = mutex.raw(); + + // OSX implementation of `pthread_cond_timedwait` is buggy + // with super long durations. When duration is greater than + // 0x100_0000_0000_0000 seconds, `pthread_cond_timedwait` + // in macOS Sierra returns error 316. + // + // This program demonstrates the issue: + // https://gist.github.com/stepancheg/198db4623a20aad2ad7cddb8fda4a63c + // + // To work around this issue, the timeout is clamped to 1000 years. + #[cfg(target_vendor = "apple")] + let dur = Duration::min(dur, Duration::from_secs(1000 * 365 * 86400)); + + let timeout = Timespec::now(Self::CLOCK).checked_add_duration(&dur); + + #[cfg(not(target_os = "nto"))] + let timeout = timeout.and_then(|t| t.to_timespec()).unwrap_or(TIMESPEC_MAX); + + #[cfg(target_os = "nto")] + let timeout = timeout.and_then(|t| t.to_timespec_capped()).unwrap_or(TIMESPEC_MAX_CAPPED); + + let r = unsafe { libc::pthread_cond_timedwait(self.raw(), mutex, &timeout) }; + assert!(r == libc::ETIMEDOUT || r == 0); + r == 0 + } +} + +#[cfg(not(any( + target_os = "android", + target_vendor = "apple", + target_os = "espidf", + target_os = "horizon", + target_os = "l4re", + target_os = "redox", + target_os = "teeos", +)))] +impl Condvar { + pub const PRECISE_TIMEOUT: bool = true; + const CLOCK: libc::clockid_t = libc::CLOCK_MONOTONIC; + + /// # Safety + /// May only be called once per instance of `Self`. + pub unsafe fn init(self: Pin<&mut Self>) { + use crate::mem::MaybeUninit; + + struct AttrGuard<'a>(pub &'a mut MaybeUninit); + impl Drop for AttrGuard<'_> { + fn drop(&mut self) { + unsafe { + let result = libc::pthread_condattr_destroy(self.0.as_mut_ptr()); + assert_eq!(result, 0); + } + } + } + + unsafe { + let mut attr = MaybeUninit::::uninit(); + let r = libc::pthread_condattr_init(attr.as_mut_ptr()); + assert_eq!(r, 0); + let attr = AttrGuard(&mut attr); + let r = libc::pthread_condattr_setclock(attr.0.as_mut_ptr(), Self::CLOCK); + assert_eq!(r, 0); + let r = libc::pthread_cond_init(self.raw(), attr.0.as_ptr()); + assert_eq!(r, 0); + } + } +} + +// `pthread_condattr_setclock` is unfortunately not supported on these platforms. +#[cfg(any( + target_os = "android", + target_vendor = "apple", + target_os = "espidf", + target_os = "horizon", + target_os = "l4re", + target_os = "redox", + target_os = "teeos", +))] +impl Condvar { + pub const PRECISE_TIMEOUT: bool = false; + const CLOCK: libc::clockid_t = libc::CLOCK_REALTIME; + + /// # Safety + /// May only be called once per instance of `Self`. + pub unsafe fn init(self: Pin<&mut Self>) { + if cfg!(any(target_os = "espidf", target_os = "horizon", target_os = "teeos")) { + // NOTE: ESP-IDF's PTHREAD_COND_INITIALIZER support is not released yet + // So on that platform, init() should always be called. + // + // Similar story for the 3DS (horizon) and for TEEOS. + let r = unsafe { libc::pthread_cond_init(self.raw(), crate::ptr::null()) }; + assert_eq!(r, 0); + } + } +} + +impl !Unpin for Condvar {} + +unsafe impl Sync for Condvar {} +unsafe impl Send for Condvar {} + +impl Drop for Condvar { + #[inline] + fn drop(&mut self) { + let r = unsafe { libc::pthread_cond_destroy(self.raw()) }; + if cfg!(target_os = "dragonfly") { + // On DragonFly pthread_cond_destroy() returns EINVAL if called on + // a condvar that was just initialized with + // libc::PTHREAD_COND_INITIALIZER. Once it is used or + // pthread_cond_init() is called, this behaviour no longer occurs. + debug_assert!(r == 0 || r == libc::EINVAL); + } else { + debug_assert_eq!(r, 0); + } + } +} diff --git a/std/src/sys/pal/unix/sync/mod.rs b/std/src/sys/pal/unix/sync/mod.rs new file mode 100644 index 0000000000000..b430ff5d8ef5f --- /dev/null +++ b/std/src/sys/pal/unix/sync/mod.rs @@ -0,0 +1,16 @@ +#![cfg(not(any( + target_os = "linux", + target_os = "android", + all(target_os = "emscripten", target_feature = "atomics"), + target_os = "freebsd", + target_os = "openbsd", + target_os = "dragonfly", + target_os = "fuchsia", +)))] +#![forbid(unsafe_op_in_unsafe_fn)] + +mod condvar; +mod mutex; + +pub use condvar::Condvar; +pub use mutex::Mutex; diff --git a/std/src/sys/pal/unix/sync/mutex.rs b/std/src/sys/pal/unix/sync/mutex.rs new file mode 100644 index 0000000000000..8ff6c3d3d15da --- /dev/null +++ b/std/src/sys/pal/unix/sync/mutex.rs @@ -0,0 +1,135 @@ +use super::super::cvt_nz; +use crate::cell::UnsafeCell; +use crate::io::Error; +use crate::mem::MaybeUninit; +use crate::pin::Pin; + +pub struct Mutex { + inner: UnsafeCell, +} + +impl Mutex { + pub fn new() -> Mutex { + Mutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) } + } + + pub(super) fn raw(&self) -> *mut libc::pthread_mutex_t { + self.inner.get() + } + + /// # Safety + /// May only be called once per instance of `Self`. + pub unsafe fn init(self: Pin<&mut Self>) { + // Issue #33770 + // + // A pthread mutex initialized with PTHREAD_MUTEX_INITIALIZER will have + // a type of PTHREAD_MUTEX_DEFAULT, which has undefined behavior if you + // try to re-lock it from the same thread when you already hold a lock + // (https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_init.html). + // This is the case even if PTHREAD_MUTEX_DEFAULT == PTHREAD_MUTEX_NORMAL + // (https://github.com/rust-lang/rust/issues/33770#issuecomment-220847521) -- in that + // case, `pthread_mutexattr_settype(PTHREAD_MUTEX_DEFAULT)` will of course be the same + // as setting it to `PTHREAD_MUTEX_NORMAL`, but not setting any mode will result in + // a Mutex where re-locking is UB. + // + // In practice, glibc takes advantage of this undefined behavior to + // implement hardware lock elision, which uses hardware transactional + // memory to avoid acquiring the lock. While a transaction is in + // progress, the lock appears to be unlocked. This isn't a problem for + // other threads since the transactional memory will abort if a conflict + // is detected, however no abort is generated when re-locking from the + // same thread. + // + // Since locking the same mutex twice will result in two aliasing &mut + // references, we instead create the mutex with type + // PTHREAD_MUTEX_NORMAL which is guaranteed to deadlock if we try to + // re-lock it from the same thread, thus avoiding undefined behavior. + unsafe { + let mut attr = MaybeUninit::::uninit(); + cvt_nz(libc::pthread_mutexattr_init(attr.as_mut_ptr())).unwrap(); + let attr = AttrGuard(&mut attr); + cvt_nz(libc::pthread_mutexattr_settype( + attr.0.as_mut_ptr(), + libc::PTHREAD_MUTEX_NORMAL, + )) + .unwrap(); + cvt_nz(libc::pthread_mutex_init(self.raw(), attr.0.as_ptr())).unwrap(); + } + } + + /// # Safety + /// * If `init` was not called on this instance, reentrant locking causes + /// undefined behaviour. + /// * Destroying a locked mutex causes undefined behaviour. + pub unsafe fn lock(self: Pin<&Self>) { + #[cold] + #[inline(never)] + fn fail(r: i32) -> ! { + let error = Error::from_raw_os_error(r); + panic!("failed to lock mutex: {error}"); + } + + let r = unsafe { libc::pthread_mutex_lock(self.raw()) }; + // As we set the mutex type to `PTHREAD_MUTEX_NORMAL` above, we expect + // the lock call to never fail. Unfortunately however, some platforms + // (Solaris) do not conform to the standard, and instead always provide + // deadlock detection. How kind of them! Unfortunately that means that + // we need to check the error code here. To save us from UB on other + // less well-behaved platforms in the future, we do it even on "good" + // platforms like macOS. See #120147 for more context. + if r != 0 { + fail(r) + } + } + + /// # Safety + /// * If `init` was not called on this instance, reentrant locking causes + /// undefined behaviour. + /// * Destroying a locked mutex causes undefined behaviour. + pub unsafe fn try_lock(self: Pin<&Self>) -> bool { + unsafe { libc::pthread_mutex_trylock(self.raw()) == 0 } + } + + /// # Safety + /// The mutex must be locked by the current thread. + pub unsafe fn unlock(self: Pin<&Self>) { + let r = unsafe { libc::pthread_mutex_unlock(self.raw()) }; + debug_assert_eq!(r, 0); + } +} + +impl !Unpin for Mutex {} + +unsafe impl Send for Mutex {} +unsafe impl Sync for Mutex {} + +impl Drop for Mutex { + fn drop(&mut self) { + // SAFETY: + // If `lock` or `init` was called, the mutex must have been pinned, so + // it is still at the same location. Otherwise, `inner` must contain + // `PTHREAD_MUTEX_INITIALIZER`, which is valid at all locations. Thus, + // this call always destroys a valid mutex. + let r = unsafe { libc::pthread_mutex_destroy(self.raw()) }; + if cfg!(target_os = "dragonfly") { + // On DragonFly pthread_mutex_destroy() returns EINVAL if called on a + // mutex that was just initialized with libc::PTHREAD_MUTEX_INITIALIZER. + // Once it is used (locked/unlocked) or pthread_mutex_init() is called, + // this behaviour no longer occurs. + debug_assert!(r == 0 || r == libc::EINVAL); + } else { + debug_assert_eq!(r, 0); + } + } +} + +struct AttrGuard<'a>(pub &'a mut MaybeUninit); + +impl Drop for AttrGuard<'_> { + fn drop(&mut self) { + unsafe { + let result = libc::pthread_mutexattr_destroy(self.0.as_mut_ptr()); + assert_eq!(result, 0); + } + } +} diff --git a/std/src/sys/pal/unix/thread.rs b/std/src/sys/pal/unix/thread.rs index 040246618360f..f657f82e6e368 100644 --- a/std/src/sys/pal/unix/thread.rs +++ b/std/src/sys/pal/unix/thread.rs @@ -45,6 +45,7 @@ unsafe impl Sync for Thread {} impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub unsafe fn new(stack: usize, p: Box) -> io::Result { let p = Box::into_raw(Box::new(p)); let mut native: libc::pthread_t = mem::zeroed(); @@ -129,25 +130,27 @@ impl Thread { } } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly"))] pub fn set_name(name: &CStr) { - const TASK_COMM_LEN: usize = 16; - unsafe { - // Available since glibc 2.12, musl 1.1.16, and uClibc 1.0.20. - let name = truncate_cstr::<{ TASK_COMM_LEN }>(name); + cfg_if::cfg_if! { + if #[cfg(target_os = "linux")] { + // Linux limits the allowed length of the name. + const TASK_COMM_LEN: usize = 16; + let name = truncate_cstr::<{ TASK_COMM_LEN }>(name); + } else { + // FreeBSD and DragonFly BSD do not enforce length limits. + } + }; + // Available since glibc 2.12, musl 1.1.16, and uClibc 1.0.20 for Linux, + // FreeBSD 12.2 and 13.0, and DragonFly BSD 6.0. let res = libc::pthread_setname_np(libc::pthread_self(), name.as_ptr()); // We have no good way of propagating errors here, but in debug-builds let's check that this actually worked. debug_assert_eq!(res, 0); } } - #[cfg(any( - target_os = "freebsd", - target_os = "dragonfly", - target_os = "openbsd", - target_os = "nuttx" - ))] + #[cfg(any(target_os = "openbsd", target_os = "nuttx"))] pub fn set_name(name: &CStr) { unsafe { libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr()); @@ -469,7 +472,7 @@ pub fn available_parallelism() -> io::Result> { unsafe { use libc::_syspage_ptr; if _syspage_ptr.is_null() { - Err(io::const_io_error!(io::ErrorKind::NotFound, "No syspage available")) + Err(io::const_error!(io::ErrorKind::NotFound, "No syspage available")) } else { let cpus = (*_syspage_ptr).num_cpu; NonZero::new(cpus as usize) @@ -509,7 +512,7 @@ pub fn available_parallelism() -> io::Result> { } } else { // FIXME: implement on Redox, l4re - Err(io::const_io_error!(io::ErrorKind::Unsupported, "Getting the number of hardware threads is not supported on the target platform")) + Err(io::const_error!(io::ErrorKind::Unsupported, "Getting the number of hardware threads is not supported on the target platform")) } } } diff --git a/std/src/sys/pal/unix/time.rs b/std/src/sys/pal/unix/time.rs index 535fe6b27d91e..e224980e95f31 100644 --- a/std/src/sys/pal/unix/time.rs +++ b/std/src/sys/pal/unix/time.rs @@ -1,3 +1,5 @@ +use core::num::niche_types::Nanoseconds; + use crate::time::Duration; use crate::{fmt, io}; @@ -15,12 +17,6 @@ pub(in crate::sys) const TIMESPEC_MAX_CAPPED: libc::timespec = libc::timespec { tv_nsec: (u64::MAX % NSEC_PER_SEC) as i64, }; -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(0)] -#[rustc_layout_scalar_valid_range_end(999_999_999)] -struct Nanoseconds(u32); - #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct SystemTime { pub(crate) t: Timespec, @@ -59,14 +55,14 @@ impl fmt::Debug for SystemTime { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("SystemTime") .field("tv_sec", &self.t.tv_sec) - .field("tv_nsec", &self.t.tv_nsec.0) + .field("tv_nsec", &self.t.tv_nsec) .finish() } } impl Timespec { const unsafe fn new_unchecked(tv_sec: i64, tv_nsec: i64) -> Timespec { - Timespec { tv_sec, tv_nsec: unsafe { Nanoseconds(tv_nsec as u32) } } + Timespec { tv_sec, tv_nsec: unsafe { Nanoseconds::new_unchecked(tv_nsec as u32) } } } pub const fn zero() -> Timespec { @@ -96,7 +92,7 @@ impl Timespec { if tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC as i64 { Ok(unsafe { Self::new_unchecked(tv_sec, tv_nsec) }) } else { - Err(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid timestamp")) + Err(io::const_error!(io::ErrorKind::InvalidData, "Invalid timestamp")) } } @@ -147,12 +143,15 @@ impl Timespec { // // Ideally this code could be rearranged such that it more // directly expresses the lower-cost behavior we want from it. - let (secs, nsec) = if self.tv_nsec.0 >= other.tv_nsec.0 { - ((self.tv_sec - other.tv_sec) as u64, self.tv_nsec.0 - other.tv_nsec.0) + let (secs, nsec) = if self.tv_nsec.as_inner() >= other.tv_nsec.as_inner() { + ( + (self.tv_sec - other.tv_sec) as u64, + self.tv_nsec.as_inner() - other.tv_nsec.as_inner(), + ) } else { ( (self.tv_sec - other.tv_sec - 1) as u64, - self.tv_nsec.0 + (NSEC_PER_SEC as u32) - other.tv_nsec.0, + self.tv_nsec.as_inner() + (NSEC_PER_SEC as u32) - other.tv_nsec.as_inner(), ) }; @@ -170,7 +169,7 @@ impl Timespec { // Nano calculations can't overflow because nanos are <1B which fit // in a u32. - let mut nsec = other.subsec_nanos() + self.tv_nsec.0; + let mut nsec = other.subsec_nanos() + self.tv_nsec.as_inner(); if nsec >= NSEC_PER_SEC as u32 { nsec -= NSEC_PER_SEC as u32; secs = secs.checked_add(1)?; @@ -182,7 +181,7 @@ impl Timespec { let mut secs = self.tv_sec.checked_sub_unsigned(other.as_secs())?; // Similar to above, nanos can't overflow. - let mut nsec = self.tv_nsec.0 as i32 - other.subsec_nanos() as i32; + let mut nsec = self.tv_nsec.as_inner() as i32 - other.subsec_nanos() as i32; if nsec < 0 { nsec += NSEC_PER_SEC as i32; secs = secs.checked_sub(1)?; @@ -194,7 +193,7 @@ impl Timespec { pub fn to_timespec(&self) -> Option { Some(libc::timespec { tv_sec: self.tv_sec.try_into().ok()?, - tv_nsec: self.tv_nsec.0.try_into().ok()?, + tv_nsec: self.tv_nsec.as_inner().try_into().ok()?, }) } @@ -203,7 +202,7 @@ impl Timespec { #[cfg(target_os = "nto")] pub(in crate::sys) fn to_timespec_capped(&self) -> Option { // Check if timeout in nanoseconds would fit into an u64 - if (self.tv_nsec.0 as u64) + if (self.tv_nsec.as_inner() as u64) .checked_add((self.tv_sec as u64).checked_mul(NSEC_PER_SEC)?) .is_none() { @@ -219,7 +218,7 @@ impl Timespec { not(target_arch = "riscv32") ))] pub fn to_timespec64(&self) -> __timespec64 { - __timespec64::new(self.tv_sec, self.tv_nsec.0 as _) + __timespec64::new(self.tv_sec, self.tv_nsec.as_inner() as _) } } @@ -293,7 +292,7 @@ impl fmt::Debug for Instant { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Instant") .field("tv_sec", &self.t.tv_sec) - .field("tv_nsec", &self.t.tv_nsec.0) + .field("tv_nsec", &self.t.tv_nsec) .finish() } } diff --git a/std/src/sys/pal/unsupported/os.rs b/std/src/sys/pal/unsupported/os.rs index 481fd62c04fe8..48de4312885fe 100644 --- a/std/src/sys/pal/unsupported/os.rs +++ b/std/src/sys/pal/unsupported/os.rs @@ -96,11 +96,11 @@ pub fn getenv(_: &OsStr) -> Option { } pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform")) + Err(io::const_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform")) } pub unsafe fn unsetenv(_: &OsStr) -> io::Result<()> { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform")) + Err(io::const_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform")) } pub fn temp_dir() -> PathBuf { diff --git a/std/src/sys/pal/wasi/fs.rs b/std/src/sys/pal/wasi/fs.rs index 3296c762cca2b..7779d2b97d7f9 100644 --- a/std/src/sys/pal/wasi/fs.rs +++ b/std/src/sys/pal/wasi/fs.rs @@ -27,10 +27,27 @@ pub struct FileAttr { pub struct ReadDir { inner: Arc, - cookie: Option, - buf: Vec, - offset: usize, - cap: usize, + state: ReadDirState, +} + +enum ReadDirState { + /// Fill `buf` with `buf.len()` bytes starting from `next_read_offset`. + FillBuffer { + next_read_offset: wasi::Dircookie, + buf: Vec, + }, + ProcessEntry { + buf: Vec, + next_read_offset: Option, + offset: usize, + }, + /// There is no more data to get in [`Self::FillBuffer`]; keep returning + /// entries via ProcessEntry until `buf` is exhausted. + RunUntilExhaustion { + buf: Vec, + offset: usize, + }, + Done, } struct ReadDirInner { @@ -147,11 +164,8 @@ impl FileType { impl ReadDir { fn new(dir: File, root: PathBuf) -> ReadDir { ReadDir { - cookie: Some(0), - buf: vec![0; 128], - offset: 0, - cap: 0, inner: Arc::new(ReadDirInner { dir, root }), + state: ReadDirState::FillBuffer { next_read_offset: 0, buf: vec![0; 128] }, } } } @@ -162,78 +176,99 @@ impl fmt::Debug for ReadDir { } } +impl core::iter::FusedIterator for ReadDir {} + impl Iterator for ReadDir { type Item = io::Result; fn next(&mut self) -> Option> { - loop { - // If we've reached the capacity of our buffer then we need to read - // some more from the OS, otherwise we pick up at our old offset. - let offset = if self.offset == self.cap { - let cookie = self.cookie.take()?; - match self.inner.dir.fd.readdir(&mut self.buf, cookie) { - Ok(bytes) => self.cap = bytes, - Err(e) => return Some(Err(e)), - } - self.offset = 0; - self.cookie = Some(cookie); - - // If we didn't actually read anything, this is in theory the - // end of the directory. - if self.cap == 0 { - self.cookie = None; - return None; - } - - 0 - } else { - self.offset - }; - let data = &self.buf[offset..self.cap]; - - // If we're not able to read a directory entry then that means it - // must have been truncated at the end of the buffer, so reset our - // offset so we can go back and reread into the buffer, picking up - // where we last left off. - let dirent_size = mem::size_of::(); - if data.len() < dirent_size { - assert!(self.cookie.is_some()); - assert!(self.buf.len() >= dirent_size); - self.offset = self.cap; - continue; - } - let (dirent, data) = data.split_at(dirent_size); - let dirent = unsafe { ptr::read_unaligned(dirent.as_ptr() as *const wasi::Dirent) }; - - // If the file name was truncated, then we need to reinvoke - // `readdir` so we truncate our buffer to start over and reread this - // descriptor. Note that if our offset is 0 that means the file name - // is massive and we need a bigger buffer. - if data.len() < dirent.d_namlen as usize { - if offset == 0 { - let amt_to_add = self.buf.capacity(); - self.buf.extend(iter::repeat(0).take(amt_to_add)); + match &mut self.state { + ReadDirState::FillBuffer { next_read_offset, ref mut buf } => { + let result = self.inner.dir.fd.readdir(buf, *next_read_offset); + match result { + Ok(read_bytes) => { + if read_bytes < buf.len() { + buf.truncate(read_bytes); + self.state = + ReadDirState::RunUntilExhaustion { buf: mem::take(buf), offset: 0 }; + } else { + debug_assert_eq!(read_bytes, buf.len()); + self.state = ReadDirState::ProcessEntry { + buf: mem::take(buf), + offset: 0, + next_read_offset: Some(*next_read_offset), + }; + } + self.next() + } + Err(e) => { + self.state = ReadDirState::Done; + return Some(Err(e)); + } } - assert!(self.cookie.is_some()); - self.offset = self.cap; - continue; } - self.cookie = Some(dirent.d_next); - self.offset = offset + dirent_size + dirent.d_namlen as usize; + ReadDirState::ProcessEntry { ref mut buf, next_read_offset, offset } => { + let contents = &buf[*offset..]; + const DIRENT_SIZE: usize = crate::mem::size_of::(); + if contents.len() >= DIRENT_SIZE { + let (dirent, data) = contents.split_at(DIRENT_SIZE); + let dirent = + unsafe { ptr::read_unaligned(dirent.as_ptr() as *const wasi::Dirent) }; + // If the file name was truncated, then we need to reinvoke + // `readdir` so we truncate our buffer to start over and reread this + // descriptor. + if data.len() < dirent.d_namlen as usize { + if buf.len() < dirent.d_namlen as usize + DIRENT_SIZE { + buf.resize(dirent.d_namlen as usize + DIRENT_SIZE, 0); + } + if let Some(next_read_offset) = *next_read_offset { + self.state = + ReadDirState::FillBuffer { next_read_offset, buf: mem::take(buf) }; + } else { + self.state = ReadDirState::Done; + } + + return self.next(); + } + next_read_offset.as_mut().map(|cookie| { + *cookie = dirent.d_next; + }); + *offset = *offset + DIRENT_SIZE + dirent.d_namlen as usize; - let name = &data[..(dirent.d_namlen as usize)]; + let name = &data[..(dirent.d_namlen as usize)]; + + // These names are skipped on all other platforms, so let's skip + // them here too + if name == b"." || name == b".." { + return self.next(); + } - // These names are skipped on all other platforms, so let's skip - // them here too - if name == b"." || name == b".." { - continue; + return Some(Ok(DirEntry { + meta: dirent, + name: name.to_vec(), + inner: self.inner.clone(), + })); + } else if let Some(next_read_offset) = *next_read_offset { + self.state = ReadDirState::FillBuffer { next_read_offset, buf: mem::take(buf) }; + } else { + self.state = ReadDirState::Done; + } + self.next() } + ReadDirState::RunUntilExhaustion { buf, offset } => { + if *offset >= buf.len() { + self.state = ReadDirState::Done; + } else { + self.state = ReadDirState::ProcessEntry { + buf: mem::take(buf), + offset: *offset, + next_read_offset: None, + }; + } - return Some(Ok(DirEntry { - meta: dirent, - name: name.to_vec(), - inner: self.inner.clone(), - })); + self.next() + } + ReadDirState::Done => None, } } } @@ -496,7 +531,7 @@ impl File { pub fn set_times(&self, times: FileTimes) -> io::Result<()> { let to_timestamp = |time: Option| match time { Some(time) if let Some(ts) = time.to_wasi_timestamp() => Ok(ts), - Some(_) => Err(io::const_io_error!( + Some(_) => Err(io::const_error!( io::ErrorKind::InvalidInput, "timestamp is too large to set as a file time" )), @@ -764,8 +799,7 @@ fn open_parent(p: &Path) -> io::Result<(ManuallyDrop, PathBuf)> { } pub fn osstr2str(f: &OsStr) -> io::Result<&str> { - f.to_str() - .ok_or_else(|| io::const_io_error!(io::ErrorKind::Uncategorized, "input must be utf-8")) + f.to_str().ok_or_else(|| io::const_error!(io::ErrorKind::Uncategorized, "input must be utf-8")) } pub fn copy(from: &Path, to: &Path) -> io::Result { @@ -811,7 +845,7 @@ fn remove_dir_all_recursive(parent: &WasiFd, path: &Path) -> io::Result<()> { for entry in ReadDir::new(fd, dummy_root) { let entry = entry?; let path = crate::str::from_utf8(&entry.name).map_err(|_| { - io::const_io_error!(io::ErrorKind::Uncategorized, "invalid utf-8 file name found") + io::const_error!(io::ErrorKind::Uncategorized, "invalid utf-8 file name found") })?; let result: io::Result<()> = try { diff --git a/std/src/sys/pal/wasi/thread.rs b/std/src/sys/pal/wasi/thread.rs index 4b83870fdea6c..f5e19f26bfe17 100644 --- a/std/src/sys/pal/wasi/thread.rs +++ b/std/src/sys/pal/wasi/thread.rs @@ -2,7 +2,6 @@ use crate::ffi::CStr; use crate::num::NonZero; -use crate::sys::unsupported; use crate::time::Duration; use crate::{io, mem}; @@ -34,6 +33,8 @@ cfg_if::cfg_if! { #[allow(non_camel_case_types)] pub type pthread_t = *mut ffi::c_void; + pub const _SC_NPROCESSORS_ONLN: ffi::c_int = 84; + extern "C" { pub fn pthread_create( native: *mut pthread_t, @@ -121,7 +122,7 @@ impl Thread { } } else { pub unsafe fn new(_stack: usize, _p: Box) -> io::Result { - unsupported() + crate::sys::unsupported() } } } @@ -187,5 +188,14 @@ impl Thread { } pub fn available_parallelism() -> io::Result> { - unsupported() + cfg_if::cfg_if! { + if #[cfg(target_feature = "atomics")] { + match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } { + -1 => Err(io::Error::last_os_error()), + cpus => NonZero::new(cpus as usize).ok_or(io::Error::UNKNOWN_THREAD_COUNT), + } + } else { + crate::sys::unsupported() + } + } } diff --git a/std/src/sys/pal/wasip2/net.rs b/std/src/sys/pal/wasip2/net.rs index 06e623df8438e..f009a51821f35 100644 --- a/std/src/sys/pal/wasip2/net.rs +++ b/std/src/sys/pal/wasip2/net.rs @@ -117,7 +117,7 @@ impl Socket { loop { let elapsed = start.elapsed(); if elapsed >= timeout { - return Err(io::const_io_error!(io::ErrorKind::TimedOut, "connection timed out")); + return Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out")); } let timeout = timeout - elapsed; diff --git a/std/src/sys/pal/windows/args.rs b/std/src/sys/pal/windows/args.rs index e9fc19bcb99c1..3447a0157e4c5 100644 --- a/std/src/sys/pal/windows/args.rs +++ b/std/src/sys/pal/windows/args.rs @@ -327,7 +327,7 @@ pub(crate) fn make_bat_command_line( force_quotes: bool, ) -> io::Result> { const INVALID_ARGUMENT_ERROR: io::Error = - io::const_io_error!(io::ErrorKind::InvalidInput, r#"batch file arguments are invalid"#); + io::const_error!(io::ErrorKind::InvalidInput, r#"batch file arguments are invalid"#); // Set the start of the command line to `cmd.exe /c "` // It is necessary to surround the command in an extra pair of quotes, // hence the trailing quote here. It will be closed after all arguments @@ -340,7 +340,7 @@ pub(crate) fn make_bat_command_line( // Windows file names cannot contain a `"` character or end with `\\`. // If the script name does then return an error. if script.contains(&(b'"' as u16)) || script.last() == Some(&(b'\\' as u16)) { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "Windows file names may not contain `\"` or end with `\\`" )); diff --git a/std/src/sys/pal/windows/c/bindings.txt b/std/src/sys/pal/windows/c/bindings.txt index 248ce3c9ff624..c06f274685c24 100644 --- a/std/src/sys/pal/windows/c/bindings.txt +++ b/std/src/sys/pal/windows/c/bindings.txt @@ -2295,6 +2295,7 @@ Windows.Win32.Storage.FileSystem.FILE_NAME_OPENED Windows.Win32.Storage.FileSystem.FILE_READ_ATTRIBUTES Windows.Win32.Storage.FileSystem.FILE_READ_DATA Windows.Win32.Storage.FileSystem.FILE_READ_EA +Windows.Win32.Storage.FileSystem.FILE_RENAME_INFO Windows.Win32.Storage.FileSystem.FILE_SHARE_DELETE Windows.Win32.Storage.FileSystem.FILE_SHARE_MODE Windows.Win32.Storage.FileSystem.FILE_SHARE_NONE @@ -2425,6 +2426,7 @@ Windows.Win32.System.Console.ENABLE_VIRTUAL_TERMINAL_PROCESSING Windows.Win32.System.Console.ENABLE_WINDOW_INPUT Windows.Win32.System.Console.ENABLE_WRAP_AT_EOL_OUTPUT Windows.Win32.System.Console.GetConsoleMode +Windows.Win32.System.Console.GetConsoleOutputCP Windows.Win32.System.Console.GetStdHandle Windows.Win32.System.Console.ReadConsoleW Windows.Win32.System.Console.STD_ERROR_HANDLE @@ -2603,5 +2605,7 @@ Windows.Win32.System.Threading.WaitForMultipleObjects Windows.Win32.System.Threading.WaitForSingleObject Windows.Win32.System.Threading.WakeAllConditionVariable Windows.Win32.System.Threading.WakeConditionVariable +Windows.Win32.System.WindowsProgramming.FILE_RENAME_FLAG_POSIX_SEMANTICS +Windows.Win32.System.WindowsProgramming.FILE_RENAME_FLAG_REPLACE_IF_EXISTS Windows.Win32.System.WindowsProgramming.PROGRESS_CONTINUE Windows.Win32.UI.Shell.GetUserProfileDirectoryW diff --git a/std/src/sys/pal/windows/c/windows_sys.rs b/std/src/sys/pal/windows/c/windows_sys.rs index 19925e59dfe9c..79513d33a1ac7 100644 --- a/std/src/sys/pal/windows/c/windows_sys.rs +++ b/std/src/sys/pal/windows/c/windows_sys.rs @@ -34,6 +34,7 @@ windows_targets::link!("kernel32.dll" "system" fn FreeEnvironmentStringsW(penv : windows_targets::link!("kernel32.dll" "system" fn GetActiveProcessorCount(groupnumber : u16) -> u32); windows_targets::link!("kernel32.dll" "system" fn GetCommandLineW() -> PCWSTR); windows_targets::link!("kernel32.dll" "system" fn GetConsoleMode(hconsolehandle : HANDLE, lpmode : *mut CONSOLE_MODE) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn GetConsoleOutputCP() -> u32); windows_targets::link!("kernel32.dll" "system" fn GetCurrentDirectoryW(nbufferlength : u32, lpbuffer : PWSTR) -> u32); windows_targets::link!("kernel32.dll" "system" fn GetCurrentProcess() -> HANDLE); windows_targets::link!("kernel32.dll" "system" fn GetCurrentProcessId() -> u32); @@ -2472,6 +2473,22 @@ pub const FILE_RANDOM_ACCESS: NTCREATEFILE_CREATE_OPTIONS = 2048u32; pub const FILE_READ_ATTRIBUTES: FILE_ACCESS_RIGHTS = 128u32; pub const FILE_READ_DATA: FILE_ACCESS_RIGHTS = 1u32; pub const FILE_READ_EA: FILE_ACCESS_RIGHTS = 8u32; +pub const FILE_RENAME_FLAG_POSIX_SEMANTICS: u32 = 2u32; +pub const FILE_RENAME_FLAG_REPLACE_IF_EXISTS: u32 = 1u32; +#[repr(C)] +#[derive(Clone, Copy)] +pub struct FILE_RENAME_INFO { + pub Anonymous: FILE_RENAME_INFO_0, + pub RootDirectory: HANDLE, + pub FileNameLength: u32, + pub FileName: [u16; 1], +} +#[repr(C)] +#[derive(Clone, Copy)] +pub union FILE_RENAME_INFO_0 { + pub ReplaceIfExists: BOOLEAN, + pub Flags: u32, +} pub const FILE_RESERVE_OPFILTER: NTCREATEFILE_CREATE_OPTIONS = 1048576u32; pub const FILE_SEQUENTIAL_ONLY: NTCREATEFILE_CREATE_OPTIONS = 4u32; pub const FILE_SESSION_AWARE: NTCREATEFILE_CREATE_OPTIONS = 262144u32; @@ -3317,6 +3334,7 @@ pub struct XSAVE_FORMAT { pub XmmRegisters: [M128A; 8], pub Reserved4: [u8; 224], } + #[cfg(target_arch = "arm")] #[repr(C)] pub struct WSADATA { diff --git a/std/src/sys/pal/windows/fs.rs b/std/src/sys/pal/windows/fs.rs index 07e4f93a37956..b3659351b8c11 100644 --- a/std/src/sys/pal/windows/fs.rs +++ b/std/src/sys/pal/windows/fs.rs @@ -1,5 +1,6 @@ use super::api::{self, WinError}; use super::{IoResult, to_u16s}; +use crate::alloc::{alloc, handle_alloc_error}; use crate::borrow::Cow; use crate::ffi::{OsStr, OsString, c_void}; use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom}; @@ -315,19 +316,31 @@ impl File { && api::get_last_error() == WinError::ALREADY_EXISTS { unsafe { - // This originally used `FileAllocationInfo` instead of - // `FileEndOfFileInfo` but that wasn't supported by WINE. - // It's arguable which fits the semantics of `OpenOptions` - // better so let's just use the more widely supported method. - let eof = c::FILE_END_OF_FILE_INFO { EndOfFile: 0 }; + // This first tries `FileAllocationInfo` but falls back to + // `FileEndOfFileInfo` in order to support WINE. + // If WINE gains support for FileAllocationInfo, we should + // remove the fallback. + let alloc = c::FILE_ALLOCATION_INFO { AllocationSize: 0 }; let result = c::SetFileInformationByHandle( handle.as_raw_handle(), - c::FileEndOfFileInfo, - (&raw const eof).cast::(), - mem::size_of::() as u32, + c::FileAllocationInfo, + (&raw const alloc).cast::(), + mem::size_of::() as u32, ); if result == 0 { - return Err(io::Error::last_os_error()); + if api::get_last_error().code != 0 { + panic!("FILE_ALLOCATION_INFO failed!!!"); + } + let eof = c::FILE_END_OF_FILE_INFO { EndOfFile: 0 }; + let result = c::SetFileInformationByHandle( + handle.as_raw_handle(), + c::FileEndOfFileInfo, + (&raw const eof).cast::(), + mem::size_of::() as u32, + ); + if result == 0 { + return Err(io::Error::last_os_error()); + } } } } @@ -677,7 +690,7 @@ impl File { ) } _ => { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Uncategorized, "Unsupported reparse point type", )); @@ -718,7 +731,7 @@ impl File { || times.modified.map_or(false, is_zero) || times.created.map_or(false, is_zero) { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "Cannot set file timestamp to 0", )); @@ -728,7 +741,7 @@ impl File { || times.modified.map_or(false, is_max) || times.created.map_or(false, is_max) { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "Cannot set file timestamp to 0xFFFF_FFFF_FFFF_FFFF", )); @@ -1223,7 +1236,142 @@ pub fn unlink(p: &Path) -> io::Result<()> { pub fn rename(old: &Path, new: &Path) -> io::Result<()> { let old = maybe_verbatim(old)?; let new = maybe_verbatim(new)?; - cvt(unsafe { c::MoveFileExW(old.as_ptr(), new.as_ptr(), c::MOVEFILE_REPLACE_EXISTING) })?; + + let new_len_without_nul_in_bytes = (new.len() - 1).try_into().unwrap(); + + // The last field of FILE_RENAME_INFO, the file name, is unsized, + // and FILE_RENAME_INFO has two padding bytes. + // Therefore we need to make sure to not allocate less than + // size_of::() bytes, which would be the case with + // 0 or 1 character paths + a null byte. + let struct_size = mem::size_of::() + .max(mem::offset_of!(c::FILE_RENAME_INFO, FileName) + new.len() * mem::size_of::()); + + let struct_size: u32 = struct_size.try_into().unwrap(); + + let create_file = |extra_access, extra_flags| { + let handle = unsafe { + HandleOrInvalid::from_raw_handle(c::CreateFileW( + old.as_ptr(), + c::SYNCHRONIZE | c::DELETE | extra_access, + c::FILE_SHARE_READ | c::FILE_SHARE_WRITE | c::FILE_SHARE_DELETE, + ptr::null(), + c::OPEN_EXISTING, + c::FILE_ATTRIBUTE_NORMAL | c::FILE_FLAG_BACKUP_SEMANTICS | extra_flags, + ptr::null_mut(), + )) + }; + + OwnedHandle::try_from(handle).map_err(|_| io::Error::last_os_error()) + }; + + // The following code replicates `MoveFileEx`'s behavior as reverse-engineered from its disassembly. + // If `old` refers to a mount point, we move it instead of the target. + let handle = match create_file(c::FILE_READ_ATTRIBUTES, c::FILE_FLAG_OPEN_REPARSE_POINT) { + Ok(handle) => { + let mut file_attribute_tag_info: MaybeUninit = + MaybeUninit::uninit(); + + let result = unsafe { + cvt(c::GetFileInformationByHandleEx( + handle.as_raw_handle(), + c::FileAttributeTagInfo, + file_attribute_tag_info.as_mut_ptr().cast(), + mem::size_of::().try_into().unwrap(), + )) + }; + + if let Err(err) = result { + if err.raw_os_error() == Some(c::ERROR_INVALID_PARAMETER as _) + || err.raw_os_error() == Some(c::ERROR_INVALID_FUNCTION as _) + { + // `GetFileInformationByHandleEx` documents that not all underlying drivers support all file information classes. + // Since we know we passed the correct arguments, this means the underlying driver didn't understand our request; + // `MoveFileEx` proceeds by reopening the file without inhibiting reparse point behavior. + None + } else { + Some(Err(err)) + } + } else { + // SAFETY: The struct has been initialized by GetFileInformationByHandleEx + let file_attribute_tag_info = unsafe { file_attribute_tag_info.assume_init() }; + let file_type = FileType::new( + file_attribute_tag_info.FileAttributes, + file_attribute_tag_info.ReparseTag, + ); + + if file_type.is_symlink() { + // The file is a mount point, junction point or symlink so + // don't reopen the file so that the link gets renamed. + Some(Ok(handle)) + } else { + // Otherwise reopen the file without inhibiting reparse point behavior. + None + } + } + } + // The underlying driver may not support `FILE_FLAG_OPEN_REPARSE_POINT`: Retry without it. + Err(err) if err.raw_os_error() == Some(c::ERROR_INVALID_PARAMETER as _) => None, + Err(err) => Some(Err(err)), + } + .unwrap_or_else(|| create_file(0, 0))?; + + let layout = core::alloc::Layout::from_size_align( + struct_size as _, + mem::align_of::(), + ) + .unwrap(); + + let file_rename_info = unsafe { alloc(layout) } as *mut c::FILE_RENAME_INFO; + + if file_rename_info.is_null() { + handle_alloc_error(layout); + } + + // SAFETY: file_rename_info is a non-null pointer pointing to memory allocated by the global allocator. + let mut file_rename_info = unsafe { Box::from_raw(file_rename_info) }; + + // SAFETY: We have allocated enough memory for a full FILE_RENAME_INFO struct and a filename. + unsafe { + (&raw mut (*file_rename_info).Anonymous).write(c::FILE_RENAME_INFO_0 { + Flags: c::FILE_RENAME_FLAG_REPLACE_IF_EXISTS | c::FILE_RENAME_FLAG_POSIX_SEMANTICS, + }); + + (&raw mut (*file_rename_info).RootDirectory).write(ptr::null_mut()); + (&raw mut (*file_rename_info).FileNameLength).write(new_len_without_nul_in_bytes); + + new.as_ptr() + .copy_to_nonoverlapping((&raw mut (*file_rename_info).FileName) as *mut u16, new.len()); + } + + // We don't use `set_file_information_by_handle` here as `FILE_RENAME_INFO` is used for both `FileRenameInfo` and `FileRenameInfoEx`. + let result = unsafe { + cvt(c::SetFileInformationByHandle( + handle.as_raw_handle(), + c::FileRenameInfoEx, + (&raw const *file_rename_info).cast::(), + struct_size, + )) + }; + + if let Err(err) = result { + if err.raw_os_error() == Some(c::ERROR_INVALID_PARAMETER as _) { + // FileRenameInfoEx and FILE_RENAME_FLAG_POSIX_SEMANTICS were added in Windows 10 1607; retry with FileRenameInfo. + file_rename_info.Anonymous.ReplaceIfExists = 1; + + cvt(unsafe { + c::SetFileInformationByHandle( + handle.as_raw_handle(), + c::FileRenameInfo, + (&raw const *file_rename_info).cast::(), + struct_size, + ) + })?; + } else { + return Err(err); + } + } + Ok(()) } @@ -1305,10 +1453,9 @@ pub fn link(original: &Path, link: &Path) -> io::Result<()> { #[cfg(target_vendor = "uwp")] pub fn link(_original: &Path, _link: &Path) -> io::Result<()> { - return Err(io::const_io_error!( - io::ErrorKind::Unsupported, - "hard link are not supported on UWP", - )); + return Err( + io::const_error!(io::ErrorKind::Unsupported, "hard link are not supported on UWP",), + ); } pub fn stat(path: &Path) -> io::Result { @@ -1495,7 +1642,7 @@ pub fn junction_point(original: &Path, link: &Path) -> io::Result<()> { let bytes = unsafe { OsStr::from_encoded_bytes_unchecked(&abs_path[2..]) }; r"\??\UNC\".encode_utf16().chain(bytes.encode_wide()).collect() } else { - return Err(io::const_io_error!(io::ErrorKind::InvalidInput, "path is not valid")); + return Err(io::const_error!(io::ErrorKind::InvalidInput, "path is not valid")); } }; // Defined inline so we don't have to mess about with variable length buffer. @@ -1512,10 +1659,7 @@ pub fn junction_point(original: &Path, link: &Path) -> io::Result<()> { } let data_len = 12 + (abs_path.len() * 2); if data_len > u16::MAX as usize { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - "`original` path is too long" - )); + return Err(io::const_error!(io::ErrorKind::InvalidInput, "`original` path is too long")); } let data_len = data_len as u16; let mut header = MountPointBuffer { diff --git a/std/src/sys/pal/windows/mod.rs b/std/src/sys/pal/windows/mod.rs index aca69490d7a1a..4282dbb54934f 100644 --- a/std/src/sys/pal/windows/mod.rs +++ b/std/src/sys/pal/windows/mod.rs @@ -113,7 +113,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind { c::ERROR_WRITE_PROTECT => return ReadOnlyFilesystem, c::ERROR_DISK_FULL | c::ERROR_HANDLE_DISK_FULL => return StorageFull, c::ERROR_SEEK_ON_DEVICE => return NotSeekable, - c::ERROR_DISK_QUOTA_EXCEEDED => return FilesystemQuotaExceeded, + c::ERROR_DISK_QUOTA_EXCEEDED => return QuotaExceeded, c::ERROR_FILE_TOO_LARGE => return FileTooLarge, c::ERROR_BUSY => return ResourceBusy, c::ERROR_POSSIBLE_DEADLOCK => return Deadlock, @@ -138,7 +138,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind { c::WSAEHOSTUNREACH => HostUnreachable, c::WSAENETDOWN => NetworkDown, c::WSAENETUNREACH => NetworkUnreachable, - c::WSAEDQUOT => FilesystemQuotaExceeded, + c::WSAEDQUOT => QuotaExceeded, _ => Uncategorized, } @@ -183,7 +183,7 @@ pub fn to_u16s>(s: S) -> crate::io::Result> { maybe_result.extend(s.encode_wide()); if unrolled_find_u16s(0, &maybe_result).is_some() { - return Err(crate::io::const_io_error!( + return Err(crate::io::const_error!( ErrorKind::InvalidInput, "strings passed to WinAPI cannot contain NULs", )); @@ -272,7 +272,7 @@ where unreachable!(); } else { // Safety: First `k` values are initialized. - let slice: &[u16] = MaybeUninit::slice_assume_init_ref(&buf[..k]); + let slice: &[u16] = buf[..k].assume_init_ref(); return Ok(f2(slice)); } } diff --git a/std/src/sys/pal/windows/net.rs b/std/src/sys/pal/windows/net.rs index fd62d1f407c27..a92853c642c06 100644 --- a/std/src/sys/pal/windows/net.rs +++ b/std/src/sys/pal/windows/net.rs @@ -267,7 +267,7 @@ impl Socket { }; match count { - 0 => Err(io::const_io_error!(io::ErrorKind::TimedOut, "connection timed out")), + 0 => Err(io::const_error!(io::ErrorKind::TimedOut, "connection timed out")), _ => { if writefds.fd_count != 1 { if let Some(e) = self.take_error()? { diff --git a/std/src/sys/pal/windows/os.rs b/std/src/sys/pal/windows/os.rs index 5242bc9da31fe..044dc2e8cd8fa 100644 --- a/std/src/sys/pal/windows/os.rs +++ b/std/src/sys/pal/windows/os.rs @@ -5,8 +5,9 @@ #[cfg(test)] mod tests; -use super::api::{self, WinError}; -use super::to_u16s; +#[cfg(not(target_vendor = "uwp"))] +use super::api::WinError; +use super::{api, to_u16s}; use crate::error::Error as StdError; use crate::ffi::{OsStr, OsString}; use crate::os::windows::ffi::EncodeWide; @@ -377,8 +378,8 @@ fn home_dir_crt() -> Option { } pub fn home_dir() -> Option { - crate::env::var_os("HOME") - .or_else(|| crate::env::var_os("USERPROFILE")) + crate::env::var_os("USERPROFILE") + .filter(|s| !s.is_empty()) .map(PathBuf::from) .or_else(home_dir_crt) } diff --git a/std/src/sys/pal/windows/process.rs b/std/src/sys/pal/windows/process.rs index 17bb03fe7af04..9332c9b49ffb9 100644 --- a/std/src/sys/pal/windows/process.rs +++ b/std/src/sys/pal/windows/process.rs @@ -10,10 +10,10 @@ use crate::collections::BTreeMap; use crate::env::consts::{EXE_EXTENSION, EXE_SUFFIX}; use crate::ffi::{OsStr, OsString}; use crate::io::{self, Error, ErrorKind}; -use crate::mem::MaybeUninit; use crate::num::NonZero; use crate::os::windows::ffi::{OsStrExt, OsStringExt}; use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle}; +use crate::os::windows::process::ProcThreadAttributeList; use crate::path::{Path, PathBuf}; use crate::sync::Mutex; use crate::sys::args::{self, Arg}; @@ -142,11 +142,11 @@ impl AsRef for EnvKey { } } -pub(crate) fn ensure_no_nuls>(str: T) -> io::Result { - if str.as_ref().encode_wide().any(|b| b == 0) { - Err(io::const_io_error!(ErrorKind::InvalidInput, "nul byte found in provided data")) +pub(crate) fn ensure_no_nuls>(s: T) -> io::Result { + if s.as_ref().encode_wide().any(|b| b == 0) { + Err(io::const_error!(ErrorKind::InvalidInput, "nul byte found in provided data")) } else { - Ok(str) + Ok(s) } } @@ -162,7 +162,6 @@ pub struct Command { stdout: Option, stderr: Option, force_quotes_enabled: bool, - proc_thread_attributes: BTreeMap, } pub enum Stdio { @@ -194,7 +193,6 @@ impl Command { stdout: None, stderr: None, force_quotes_enabled: false, - proc_thread_attributes: Default::default(), } } @@ -248,21 +246,19 @@ impl Command { self.cwd.as_ref().map(Path::new) } - pub unsafe fn raw_attribute( + pub fn spawn( &mut self, - attribute: usize, - value: T, - ) { - self.proc_thread_attributes.insert(attribute, ProcThreadAttributeValue { - size: mem::size_of::(), - data: Box::new(value), - }); + default: Stdio, + needs_stdin: bool, + ) -> io::Result<(Process, StdioPipes)> { + self.spawn_with_attributes(default, needs_stdin, None) } - pub fn spawn( + pub fn spawn_with_attributes( &mut self, default: Stdio, needs_stdin: bool, + proc_thread_attribute_list: Option<&ProcThreadAttributeList<'_>>, ) -> io::Result<(Process, StdioPipes)> { let maybe_env = self.env.capture_if_changed(); @@ -355,18 +351,18 @@ impl Command { let si_ptr: *mut c::STARTUPINFOW; - let mut proc_thread_attribute_list; let mut si_ex; - if !self.proc_thread_attributes.is_empty() { + if let Some(proc_thread_attribute_list) = proc_thread_attribute_list { si.cb = mem::size_of::() as u32; flags |= c::EXTENDED_STARTUPINFO_PRESENT; - proc_thread_attribute_list = - make_proc_thread_attribute_list(&self.proc_thread_attributes)?; si_ex = c::STARTUPINFOEXW { StartupInfo: si, - lpAttributeList: proc_thread_attribute_list.0.as_mut_ptr() as _, + // SAFETY: Casting this `*const` pointer to a `*mut` pointer is "safe" + // here because windows does not internally mutate the attribute list. + // Ideally this should be reflected in the interface of the `windows-sys` crate. + lpAttributeList: proc_thread_attribute_list.as_ptr().cast::().cast_mut(), }; si_ptr = (&raw mut si_ex) as _; } else { @@ -439,10 +435,9 @@ fn resolve_exe<'a>( ) -> io::Result> { // Early return if there is no filename. if exe_path.is_empty() || path::has_trailing_slash(exe_path) { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - "program path has no file name", - )); + return Err( + io::const_error!(io::ErrorKind::InvalidInput, "program path has no file name",), + ); } // Test if the file name has the `exe` extension. // This does a case-insensitive `ends_with`. @@ -492,7 +487,7 @@ fn resolve_exe<'a>( } } // If we get here then the executable cannot be found. - Err(io::const_io_error!(io::ErrorKind::NotFound, "program not found")) + Err(io::const_error!(io::ErrorKind::NotFound, "program not found")) } // Calls `f` for every path that should be used to find an executable. @@ -897,79 +892,6 @@ fn make_dirp(d: Option<&OsString>) -> io::Result<(*const u16, Vec)> { } } -struct ProcThreadAttributeList(Box<[MaybeUninit]>); - -impl Drop for ProcThreadAttributeList { - fn drop(&mut self) { - let lp_attribute_list = self.0.as_mut_ptr() as _; - unsafe { c::DeleteProcThreadAttributeList(lp_attribute_list) } - } -} - -/// Wrapper around the value data to be used as a Process Thread Attribute. -struct ProcThreadAttributeValue { - data: Box, - size: usize, -} - -fn make_proc_thread_attribute_list( - attributes: &BTreeMap, -) -> io::Result { - // To initialize our ProcThreadAttributeList, we need to determine - // how many bytes to allocate for it. The Windows API simplifies this process - // by allowing us to call `InitializeProcThreadAttributeList` with - // a null pointer to retrieve the required size. - let mut required_size = 0; - let Ok(attribute_count) = attributes.len().try_into() else { - return Err(io::const_io_error!( - ErrorKind::InvalidInput, - "maximum number of ProcThreadAttributes exceeded", - )); - }; - unsafe { - c::InitializeProcThreadAttributeList( - ptr::null_mut(), - attribute_count, - 0, - &mut required_size, - ) - }; - - let mut proc_thread_attribute_list = - ProcThreadAttributeList(vec![MaybeUninit::uninit(); required_size].into_boxed_slice()); - - // Once we've allocated the necessary memory, it's safe to invoke - // `InitializeProcThreadAttributeList` to properly initialize the list. - cvt(unsafe { - c::InitializeProcThreadAttributeList( - proc_thread_attribute_list.0.as_mut_ptr() as *mut _, - attribute_count, - 0, - &mut required_size, - ) - })?; - - // # Add our attributes to the buffer. - // It's theoretically possible for the attribute count to exceed a u32 value. - // Therefore, we ensure that we don't add more attributes than the buffer was initialized for. - for (&attribute, value) in attributes.iter().take(attribute_count as usize) { - let value_ptr = (&raw const *value.data) as _; - cvt(unsafe { - c::UpdateProcThreadAttribute( - proc_thread_attribute_list.0.as_mut_ptr() as _, - 0, - attribute, - value_ptr, - value.size, - ptr::null_mut(), - ptr::null_mut(), - ) - })?; - } - - Ok(proc_thread_attribute_list) -} - pub struct CommandArgs<'a> { iter: crate::slice::Iter<'a, Arg>, } diff --git a/std/src/sys/pal/windows/stack_overflow.rs b/std/src/sys/pal/windows/stack_overflow.rs index 467e21ab56a28..734cd30bed08f 100644 --- a/std/src/sys/pal/windows/stack_overflow.rs +++ b/std/src/sys/pal/windows/stack_overflow.rs @@ -18,10 +18,10 @@ unsafe extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POIN let code = rec.ExceptionCode; if code == c::EXCEPTION_STACK_OVERFLOW { - rtprintpanic!( - "\nthread '{}' has overflowed its stack\n", - thread::current().name().unwrap_or("") - ); + thread::with_current_name(|name| { + let name = name.unwrap_or(""); + rtprintpanic!("\nthread '{name}' has overflowed its stack\n"); + }); } c::EXCEPTION_CONTINUE_SEARCH } diff --git a/std/src/sys/pal/windows/stdio.rs b/std/src/sys/pal/windows/stdio.rs index 575f2250eb91c..fd3f559ba1901 100644 --- a/std/src/sys/pal/windows/stdio.rs +++ b/std/src/sys/pal/windows/stdio.rs @@ -84,21 +84,43 @@ fn is_console(handle: c::HANDLE) -> bool { unsafe { c::GetConsoleMode(handle, &mut mode) != 0 } } +/// Returns true if the attached console's code page is currently UTF-8. +#[cfg(not(target_vendor = "win7"))] +fn is_utf8_console() -> bool { + unsafe { c::GetConsoleOutputCP() == c::CP_UTF8 } +} + +#[cfg(target_vendor = "win7")] +fn is_utf8_console() -> bool { + // Windows 7 has a fun "feature" where WriteFile on a console handle will return + // the number of UTF-16 code units written and not the number of bytes from the input string. + // So we always claim the console isn't UTF-8 to trigger the WriteConsole fallback code. + false +} + fn write(handle_id: u32, data: &[u8], incomplete_utf8: &mut IncompleteUtf8) -> io::Result { if data.is_empty() { return Ok(0); } let handle = get_handle(handle_id)?; - if !is_console(handle) { + if !is_console(handle) || is_utf8_console() { unsafe { let handle = Handle::from_raw_handle(handle); let ret = handle.write(data); let _ = handle.into_raw_handle(); // Don't close the handle return ret; } + } else { + write_console_utf16(data, incomplete_utf8, handle) } +} +fn write_console_utf16( + data: &[u8], + incomplete_utf8: &mut IncompleteUtf8, + handle: c::HANDLE, +) -> io::Result { if incomplete_utf8.len > 0 { assert!( incomplete_utf8.len < 4, @@ -107,7 +129,7 @@ fn write(handle_id: u32, data: &[u8], incomplete_utf8: &mut IncompleteUtf8) -> i if data[0] >> 6 != 0b10 { // not a continuation byte - reject incomplete_utf8.len = 0; - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidData, "Windows stdio in console mode does not support writing non-UTF-8 byte sequences", )); @@ -129,7 +151,7 @@ fn write(handle_id: u32, data: &[u8], incomplete_utf8: &mut IncompleteUtf8) -> i return Ok(1); } Err(_) => { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidData, "Windows stdio in console mode does not support writing non-UTF-8 byte sequences", )); @@ -153,7 +175,7 @@ fn write(handle_id: u32, data: &[u8], incomplete_utf8: &mut IncompleteUtf8) -> i incomplete_utf8.len = 1; return Ok(1); } else { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidData, "Windows stdio in console mode does not support writing non-UTF-8 byte sequences", )); @@ -185,7 +207,7 @@ fn write_valid_utf8_to_console(handle: c::HANDLE, utf8: &str) -> io::Result return Ok(bytes_copied + value), Err(e) => return Err(e), @@ -392,7 +414,7 @@ fn utf16_to_utf8(utf16: &[u16], utf8: &mut [u8]) -> io::Result { }; if result == 0 { // We can't really do any better than forget all data and return an error. - Err(io::const_io_error!( + Err(io::const_error!( io::ErrorKind::InvalidData, "Windows stdin in console mode does not support non-UTF-16 input; \ encountered unpaired surrogate", diff --git a/std/src/sys/pal/windows/thread.rs b/std/src/sys/pal/windows/thread.rs index 2c8ce42f4148b..45e52cf4d047f 100644 --- a/std/src/sys/pal/windows/thread.rs +++ b/std/src/sys/pal/windows/thread.rs @@ -19,6 +19,7 @@ pub struct Thread { impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub unsafe fn new(stack: usize, p: Box) -> io::Result { let p = Box::into_raw(Box::new(p)); diff --git a/std/src/sys/pal/xous/net/dns.rs b/std/src/sys/pal/xous/net/dns.rs index 1a2b56b4da5d3..ff6e49ed2d430 100644 --- a/std/src/sys/pal/xous/net/dns.rs +++ b/std/src/sys/pal/xous/net/dns.rs @@ -107,7 +107,7 @@ impl TryFrom<&str> for LookupHost { ($e:expr, $msg:expr) => { match $e { Some(r) => r, - None => return Err(io::const_io_error!(io::ErrorKind::InvalidInput, &$msg)), + None => return Err(io::const_error!(io::ErrorKind::InvalidInput, &$msg)), } }; } @@ -123,7 +123,6 @@ impl TryFrom<(&str, u16)> for LookupHost { type Error = io::Error; fn try_from(v: (&str, u16)) -> io::Result { - lookup(v.0, v.1) - .map_err(|_e| io::const_io_error!(io::ErrorKind::InvalidInput, &"DNS failure")) + lookup(v.0, v.1).map_err(|_e| io::const_error!(io::ErrorKind::InvalidInput, &"DNS failure")) } } diff --git a/std/src/sys/pal/xous/net/tcplistener.rs b/std/src/sys/pal/xous/net/tcplistener.rs index ddfb289162b69..640a02a64f525 100644 --- a/std/src/sys/pal/xous/net/tcplistener.rs +++ b/std/src/sys/pal/xous/net/tcplistener.rs @@ -9,7 +9,7 @@ use crate::{fmt, io}; macro_rules! unimpl { () => { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Unsupported, &"This function is not yet implemented", )); @@ -71,7 +71,7 @@ impl TcpListener { 0, 4096, ) else { - return Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Invalid response")); + return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Invalid response")); }; // The first four bytes should be zero upon success, and will be nonzero @@ -80,16 +80,13 @@ impl TcpListener { if response[0] != 0 || valid == 0 { let errcode = response[1]; if errcode == NetError::SocketInUse as u8 { - return Err(io::const_io_error!(io::ErrorKind::ResourceBusy, &"Socket in use")); + return Err(io::const_error!(io::ErrorKind::ResourceBusy, &"Socket in use")); } else if errcode == NetError::Invalid as u8 { - return Err(io::const_io_error!( - io::ErrorKind::AddrNotAvailable, - &"Invalid address" - )); + return Err(io::const_error!(io::ErrorKind::AddrNotAvailable, &"Invalid address")); } else if errcode == NetError::LibraryError as u8 { - return Err(io::const_io_error!(io::ErrorKind::Other, &"Library error")); + return Err(io::const_error!(io::ErrorKind::Other, &"Library error")); } else { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Other, &"Unable to connect or internal error" )); @@ -130,16 +127,15 @@ impl TcpListener { if receive_request.raw[0] != 0 { // error case if receive_request.raw[1] == NetError::TimedOut as u8 { - return Err(io::const_io_error!(io::ErrorKind::TimedOut, &"accept timed out",)); + return Err(io::const_error!(io::ErrorKind::TimedOut, &"accept timed out",)); } else if receive_request.raw[1] == NetError::WouldBlock as u8 { - return Err(io::const_io_error!( - io::ErrorKind::WouldBlock, - &"accept would block", - )); + return Err( + io::const_error!(io::ErrorKind::WouldBlock, &"accept would block",), + ); } else if receive_request.raw[1] == NetError::LibraryError as u8 { - return Err(io::const_io_error!(io::ErrorKind::Other, &"Library error")); + return Err(io::const_error!(io::ErrorKind::Other, &"Library error")); } else { - return Err(io::const_io_error!(io::ErrorKind::Other, &"library error",)); + return Err(io::const_error!(io::ErrorKind::Other, &"library error",)); } } else { // accept successful @@ -163,7 +159,7 @@ impl TcpListener { port, ) } else { - return Err(io::const_io_error!(io::ErrorKind::Other, &"library error",)); + return Err(io::const_error!(io::ErrorKind::Other, &"library error",)); }; // replenish the listener @@ -175,7 +171,7 @@ impl TcpListener { Ok((TcpStream::from_listener(stream_fd, self.local.port(), port, addr), addr)) } } else { - Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unable to accept")) + Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unable to accept")) } } @@ -192,7 +188,7 @@ impl TcpListener { services::net_server(), services::NetBlockingScalar::StdSetTtlTcp(self.fd.load(Ordering::Relaxed), ttl).into(), ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) .map(|_| ()) } @@ -201,7 +197,7 @@ impl TcpListener { services::net_server(), services::NetBlockingScalar::StdGetTtlTcp(self.fd.load(Ordering::Relaxed)).into(), ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) .map(|res| res[0] as _)?) } diff --git a/std/src/sys/pal/xous/net/tcpstream.rs b/std/src/sys/pal/xous/net/tcpstream.rs index 03442cf2fcdfd..572dd6b3b6398 100644 --- a/std/src/sys/pal/xous/net/tcpstream.rs +++ b/std/src/sys/pal/xous/net/tcpstream.rs @@ -10,7 +10,7 @@ use crate::time::Duration; macro_rules! unimpl { () => { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Unsupported, &"This function is not yet implemented", )); @@ -96,7 +96,7 @@ impl TcpStream { 0, 4096, ) else { - return Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Invalid response")); + return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Invalid response")); }; // The first four bytes should be zero upon success, and will be nonzero @@ -106,14 +106,11 @@ impl TcpStream { // errcode is a u8 but stuck in a u16 where the upper byte is invalid. Mask & decode accordingly. let errcode = response[0]; if errcode == NetError::SocketInUse as u8 { - return Err(io::const_io_error!(io::ErrorKind::ResourceBusy, &"Socket in use",)); + return Err(io::const_error!(io::ErrorKind::ResourceBusy, &"Socket in use",)); } else if errcode == NetError::Unaddressable as u8 { - return Err(io::const_io_error!( - io::ErrorKind::AddrNotAvailable, - &"Invalid address", - )); + return Err(io::const_error!(io::ErrorKind::AddrNotAvailable, &"Invalid address",)); } else { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, &"Unable to connect or internal error", )); @@ -199,7 +196,7 @@ impl TcpStream { self.read_timeout.load(Ordering::Relaxed) as usize, data_to_read, ) else { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, &"Library failure: wrong message type or messaging error" )); @@ -215,14 +212,14 @@ impl TcpStream { if result[0] != 0 { if result[1] == 8 { // timed out - return Err(io::const_io_error!(io::ErrorKind::TimedOut, &"Timeout",)); + return Err(io::const_error!(io::ErrorKind::TimedOut, &"Timeout",)); } if result[1] == 9 { // would block - return Err(io::const_io_error!(io::ErrorKind::WouldBlock, &"Would block",)); + return Err(io::const_error!(io::ErrorKind::WouldBlock, &"Would block",)); } } - Err(io::const_io_error!(io::ErrorKind::Other, &"recv_slice failure")) + Err(io::const_error!(io::ErrorKind::Other, &"recv_slice failure")) } } @@ -261,23 +258,20 @@ impl TcpStream { self.write_timeout.load(Ordering::Relaxed) as usize, buf_len, ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Internal error")))?; + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Internal error")))?; if send_request.raw[0] != 0 { if send_request.raw[4] == 8 { // timed out - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::BrokenPipe, &"Timeout or connection closed", )); } else if send_request.raw[4] == 9 { // would block - return Err(io::const_io_error!(io::ErrorKind::WouldBlock, &"Would block",)); + return Err(io::const_error!(io::ErrorKind::WouldBlock, &"Would block",)); } else { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - &"Error when sending", - )); + return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Error when sending",)); } } Ok(u32::from_le_bytes([ @@ -310,7 +304,7 @@ impl TcpStream { 0, 0, ) else { - return Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Internal error")); + return Err(io::const_error!(io::ErrorKind::InvalidInput, &"Internal error")); }; let mut i = get_addr.raw.iter(); match *i.next().unwrap() { @@ -330,7 +324,7 @@ impl TcpStream { } Ok(SocketAddr::V6(SocketAddrV6::new(new_addr.into(), self.local_port, 0, 0))) } - _ => Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Internal error")), + _ => Err(io::const_error!(io::ErrorKind::InvalidInput, &"Internal error")), } } @@ -339,7 +333,7 @@ impl TcpStream { services::net_server(), services::NetBlockingScalar::StdTcpStreamShutdown(self.fd, how).into(), ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) .map(|_| ()) } @@ -361,7 +355,7 @@ impl TcpStream { services::net_server(), services::NetBlockingScalar::StdSetNodelay(self.fd, enabled).into(), ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) .map(|_| ()) } @@ -370,7 +364,7 @@ impl TcpStream { services::net_server(), services::NetBlockingScalar::StdGetNodelay(self.fd).into(), ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) .map(|res| res[0] != 0)?) } @@ -382,7 +376,7 @@ impl TcpStream { services::net_server(), services::NetBlockingScalar::StdSetTtlTcp(self.fd, ttl).into(), ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) .map(|_| ()) } @@ -391,7 +385,7 @@ impl TcpStream { services::net_server(), services::NetBlockingScalar::StdGetTtlTcp(self.fd).into(), ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) .map(|res| res[0] as _)?) } diff --git a/std/src/sys/pal/xous/net/udp.rs b/std/src/sys/pal/xous/net/udp.rs index de5133280ba9d..1b7ecac6d3a7e 100644 --- a/std/src/sys/pal/xous/net/udp.rs +++ b/std/src/sys/pal/xous/net/udp.rs @@ -11,7 +11,7 @@ use crate::{fmt, io}; macro_rules! unimpl { () => { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Unsupported, &"This function is not yet implemented", )); @@ -72,16 +72,16 @@ impl UdpSocket { if response[0] != 0 || valid == 0 { let errcode = response[1]; if errcode == NetError::SocketInUse as u8 { - return Err(io::const_io_error!(io::ErrorKind::ResourceBusy, &"Socket in use")); + return Err(io::const_error!(io::ErrorKind::ResourceBusy, &"Socket in use")); } else if errcode == NetError::Invalid as u8 { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, &"Port can't be 0 or invalid address" )); } else if errcode == NetError::LibraryError as u8 { - return Err(io::const_io_error!(io::ErrorKind::Other, &"Library error")); + return Err(io::const_error!(io::ErrorKind::Other, &"Library error")); } else { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Other, &"Unable to connect or internal error" )); @@ -98,13 +98,13 @@ impl UdpSocket { nonblocking: Cell::new(false), }); } - Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Invalid response")) + Err(io::const_error!(io::ErrorKind::InvalidInput, &"Invalid response")) } pub fn peer_addr(&self) -> io::Result { match self.remote.get() { Some(dest) => Ok(dest), - None => Err(io::const_io_error!(io::ErrorKind::NotConnected, &"No peer specified")), + None => Err(io::const_error!(io::ErrorKind::NotConnected, &"No peer specified")), } } @@ -141,16 +141,13 @@ impl UdpSocket { if receive_request.raw[0] != 0 { // error case if receive_request.raw[1] == NetError::TimedOut as u8 { - return Err(io::const_io_error!(io::ErrorKind::TimedOut, &"recv timed out",)); + return Err(io::const_error!(io::ErrorKind::TimedOut, &"recv timed out",)); } else if receive_request.raw[1] == NetError::WouldBlock as u8 { - return Err(io::const_io_error!( - io::ErrorKind::WouldBlock, - &"recv would block", - )); + return Err(io::const_error!(io::ErrorKind::WouldBlock, &"recv would block",)); } else if receive_request.raw[1] == NetError::LibraryError as u8 { - return Err(io::const_io_error!(io::ErrorKind::Other, &"Library error")); + return Err(io::const_error!(io::ErrorKind::Other, &"Library error")); } else { - return Err(io::const_io_error!(io::ErrorKind::Other, &"library error",)); + return Err(io::const_error!(io::ErrorKind::Other, &"library error",)); } } else { let rr = &receive_request.raw; @@ -173,7 +170,7 @@ impl UdpSocket { port, ) } else { - return Err(io::const_io_error!(io::ErrorKind::Other, &"library error",)); + return Err(io::const_error!(io::ErrorKind::Other, &"library error",)); }; for (&s, d) in rr[22..22 + rxlen as usize].iter().zip(buf.iter_mut()) { *d = s; @@ -181,7 +178,7 @@ impl UdpSocket { Ok((rxlen as usize, addr)) } } else { - Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unable to recv")) + Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unable to recv")) } } @@ -211,7 +208,7 @@ impl UdpSocket { if let Some(addr) = self.remote.get() { self.send_to(buf, &addr) } else { - Err(io::const_io_error!(io::ErrorKind::NotConnected, &"No remote specified")) + Err(io::const_error!(io::ErrorKind::NotConnected, &"No remote specified")) } } @@ -282,22 +279,19 @@ impl UdpSocket { if response[0] != 0 || valid == 0 { let errcode = response[1]; if errcode == NetError::SocketInUse as u8 { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::ResourceBusy, &"Socket in use" )); } else if errcode == NetError::Invalid as u8 { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, &"Socket not valid" )); } else if errcode == NetError::LibraryError as u8 { - return Err(io::const_io_error!( - io::ErrorKind::Other, - &"Library error" - )); + return Err(io::const_error!(io::ErrorKind::Other, &"Library error")); } else { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::Other, &"Unable to connect" )); @@ -309,7 +303,7 @@ impl UdpSocket { } Err(crate::os::xous::ffi::Error::ServerQueueFull) => { if now.elapsed() >= write_timeout { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::WouldBlock, &"Write timed out" )); @@ -318,7 +312,7 @@ impl UdpSocket { crate::thread::yield_now(); } } - _ => return Err(io::const_io_error!(io::ErrorKind::Other, &"Library error")), + _ => return Err(io::const_error!(io::ErrorKind::Other, &"Library error")), } } } @@ -372,7 +366,7 @@ impl UdpSocket { services::net_server(), services::NetBlockingScalar::StdSetTtlUdp(self.fd, ttl).into(), ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) .map(|_| ()) } @@ -381,7 +375,7 @@ impl UdpSocket { services::net_server(), services::NetBlockingScalar::StdGetTtlUdp(self.fd).into(), ) - .or(Err(io::const_io_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) + .or(Err(io::const_error!(io::ErrorKind::InvalidInput, &"Unexpected return value"))) .map(|res| res[0] as _)?) } diff --git a/std/src/sys/pal/zkvm/os.rs b/std/src/sys/pal/zkvm/os.rs index 5d224ffd1ba5a..868b19e33b672 100644 --- a/std/src/sys/pal/zkvm/os.rs +++ b/std/src/sys/pal/zkvm/os.rs @@ -115,11 +115,11 @@ pub fn getenv(varname: &OsStr) -> Option { } pub unsafe fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform")) + Err(io::const_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform")) } pub unsafe fn unsetenv(_: &OsStr) -> io::Result<()> { - Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform")) + Err(io::const_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform")) } pub fn temp_dir() -> PathBuf { diff --git a/std/src/sys/path/sgx.rs b/std/src/sys/path/sgx.rs index c805c15e70245..32c7752f605d9 100644 --- a/std/src/sys/path/sgx.rs +++ b/std/src/sys/path/sgx.rs @@ -23,3 +23,7 @@ pub const MAIN_SEP: char = '/'; pub(crate) fn absolute(_path: &Path) -> io::Result { unsupported() } + +pub(crate) fn is_absolute(path: &Path) -> bool { + path.has_root() && path.prefix().is_some() +} diff --git a/std/src/sys/path/unix.rs b/std/src/sys/path/unix.rs index 2a7c025c3c46a..361e99964f18c 100644 --- a/std/src/sys/path/unix.rs +++ b/std/src/sys/path/unix.rs @@ -60,3 +60,14 @@ pub(crate) fn absolute(path: &Path) -> io::Result { Ok(normalized) } + +pub(crate) fn is_absolute(path: &Path) -> bool { + if cfg!(target_os = "redox") { + // FIXME: Allow Redox prefixes + path.has_root() || crate::path::has_redox_scheme(path.as_u8_slice()) + } else if cfg!(any(unix, target_os = "hermit", target_os = "wasi")) { + path.has_root() + } else { + path.has_root() && path.prefix().is_some() + } +} diff --git a/std/src/sys/path/unsupported_backslash.rs b/std/src/sys/path/unsupported_backslash.rs index 855f443678c6c..30b06c132c98d 100644 --- a/std/src/sys/path/unsupported_backslash.rs +++ b/std/src/sys/path/unsupported_backslash.rs @@ -24,3 +24,7 @@ pub const MAIN_SEP: char = '\\'; pub(crate) fn absolute(_path: &Path) -> io::Result { unsupported() } + +pub(crate) fn is_absolute(path: &Path) -> bool { + path.has_root() && path.prefix().is_some() +} diff --git a/std/src/sys/path/windows.rs b/std/src/sys/path/windows.rs index 9267602cb9715..1c53472191699 100644 --- a/std/src/sys/path/windows.rs +++ b/std/src/sys/path/windows.rs @@ -328,7 +328,7 @@ pub(crate) fn absolute(path: &Path) -> io::Result { if prefix.map(|x| x.is_verbatim()).unwrap_or(false) { // NULs in verbatim paths are rejected for consistency. if path.as_encoded_bytes().contains(&0) { - return Err(io::const_io_error!( + return Err(io::const_error!( io::ErrorKind::InvalidInput, "strings passed to WinAPI cannot contain NULs", )); @@ -346,3 +346,7 @@ pub(crate) fn absolute(path: &Path) -> io::Result { os2path, ) } + +pub(crate) fn is_absolute(path: &Path) -> bool { + path.has_root() && path.prefix().is_some() +} diff --git a/std/src/sys/personality/gcc.rs b/std/src/sys/personality/gcc.rs index ad596ecff65d5..88a25caeff0df 100644 --- a/std/src/sys/personality/gcc.rs +++ b/std/src/sys/personality/gcc.rs @@ -5,7 +5,7 @@ //! documents linked from it. //! These are also good reads: //! * -//! * +//! * //! * //! //! ## A brief summary diff --git a/std/src/sys/personality/mod.rs b/std/src/sys/personality/mod.rs index 9754e840d151a..2e1d2e53a2979 100644 --- a/std/src/sys/personality/mod.rs +++ b/std/src/sys/personality/mod.rs @@ -31,7 +31,7 @@ cfg_if::cfg_if! { target_os = "psp", target_os = "xous", target_os = "solid_asp3", - all(target_family = "unix", not(target_os = "espidf"), not(target_os = "l4re"), not(target_os = "rtems"), not(target_os = "nuttx")), + all(target_family = "unix", not(target_os = "espidf"), not(target_os = "l4re"), not(target_os = "nuttx")), all(target_vendor = "fortanix", target_env = "sgx"), ))] { mod gcc; diff --git a/std/src/sys/sync/condvar/no_threads.rs b/std/src/sys/sync/condvar/no_threads.rs index 2a67ed766aa0c..18d97d4b17ab0 100644 --- a/std/src/sys/sync/condvar/no_threads.rs +++ b/std/src/sys/sync/condvar/no_threads.rs @@ -1,11 +1,11 @@ use crate::sys::sync::Mutex; +use crate::thread::sleep; use crate::time::Duration; pub struct Condvar {} impl Condvar { #[inline] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_locks", since = "1.63.0"))] pub const fn new() -> Condvar { Condvar {} } @@ -20,7 +20,8 @@ impl Condvar { panic!("condvar wait not supported") } - pub unsafe fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool { - panic!("condvar wait not supported"); + pub unsafe fn wait_timeout(&self, _mutex: &Mutex, dur: Duration) -> bool { + sleep(dur); + false } } diff --git a/std/src/sys/sync/condvar/pthread.rs b/std/src/sys/sync/condvar/pthread.rs index cee728e35cdfc..5bb7431eecf0c 100644 --- a/std/src/sys/sync/condvar/pthread.rs +++ b/std/src/sys/sync/condvar/pthread.rs @@ -1,196 +1,88 @@ -use crate::cell::UnsafeCell; +#![forbid(unsafe_op_in_unsafe_fn)] + +use crate::pin::Pin; use crate::ptr; -use crate::sync::atomic::AtomicPtr; +use crate::sync::atomic::AtomicUsize; use crate::sync::atomic::Ordering::Relaxed; +use crate::sys::pal::sync as pal; use crate::sys::sync::{Mutex, OnceBox}; -#[cfg(not(target_os = "nto"))] -use crate::sys::time::TIMESPEC_MAX; -#[cfg(target_os = "nto")] -use crate::sys::time::TIMESPEC_MAX_CAPPED; -use crate::time::Duration; - -struct AllocatedCondvar(UnsafeCell); +use crate::time::{Duration, Instant}; pub struct Condvar { - inner: OnceBox, - mutex: AtomicPtr, -} - -unsafe impl Send for AllocatedCondvar {} -unsafe impl Sync for AllocatedCondvar {} - -impl AllocatedCondvar { - fn new() -> Box { - let condvar = Box::new(AllocatedCondvar(UnsafeCell::new(libc::PTHREAD_COND_INITIALIZER))); - - cfg_if::cfg_if! { - if #[cfg(any( - target_os = "l4re", - target_os = "android", - target_os = "redox", - target_vendor = "apple", - ))] { - // `pthread_condattr_setclock` is unfortunately not supported on these platforms. - } else if #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "teeos"))] { - // NOTE: ESP-IDF's PTHREAD_COND_INITIALIZER support is not released yet - // So on that platform, init() should always be called - // Moreover, that platform does not have pthread_condattr_setclock support, - // hence that initialization should be skipped as well - // - // Similar story for the 3DS (horizon). - let r = unsafe { libc::pthread_cond_init(condvar.0.get(), crate::ptr::null()) }; - assert_eq!(r, 0); - } else { - use crate::mem::MaybeUninit; - let mut attr = MaybeUninit::::uninit(); - let r = unsafe { libc::pthread_condattr_init(attr.as_mut_ptr()) }; - assert_eq!(r, 0); - let r = unsafe { libc::pthread_condattr_setclock(attr.as_mut_ptr(), libc::CLOCK_MONOTONIC) }; - assert_eq!(r, 0); - let r = unsafe { libc::pthread_cond_init(condvar.0.get(), attr.as_ptr()) }; - assert_eq!(r, 0); - let r = unsafe { libc::pthread_condattr_destroy(attr.as_mut_ptr()) }; - assert_eq!(r, 0); - } - } - - condvar - } -} - -impl Drop for AllocatedCondvar { - #[inline] - fn drop(&mut self) { - let r = unsafe { libc::pthread_cond_destroy(self.0.get()) }; - if cfg!(target_os = "dragonfly") { - // On DragonFly pthread_cond_destroy() returns EINVAL if called on - // a condvar that was just initialized with - // libc::PTHREAD_COND_INITIALIZER. Once it is used or - // pthread_cond_init() is called, this behavior no longer occurs. - debug_assert!(r == 0 || r == libc::EINVAL); - } else { - debug_assert_eq!(r, 0); - } - } + cvar: OnceBox, + mutex: AtomicUsize, } impl Condvar { pub const fn new() -> Condvar { - Condvar { inner: OnceBox::new(), mutex: AtomicPtr::new(ptr::null_mut()) } + Condvar { cvar: OnceBox::new(), mutex: AtomicUsize::new(0) } } - fn get(&self) -> *mut libc::pthread_cond_t { - self.inner.get_or_init(AllocatedCondvar::new).0.get() + #[inline] + fn get(&self) -> Pin<&pal::Condvar> { + self.cvar.get_or_init(|| { + let mut cvar = Box::pin(pal::Condvar::new()); + // SAFETY: we only call `init` once per `pal::Condvar`, namely here. + unsafe { cvar.as_mut().init() }; + cvar + }) } #[inline] - fn verify(&self, mutex: *mut libc::pthread_mutex_t) { - // Relaxed is okay here because we never read through `self.addr`, and only use it to + fn verify(&self, mutex: Pin<&pal::Mutex>) { + let addr = ptr::from_ref::(&mutex).addr(); + // Relaxed is okay here because we never read through `self.mutex`, and only use it to // compare addresses. - match self.mutex.compare_exchange(ptr::null_mut(), mutex, Relaxed, Relaxed) { - Ok(_) => {} // Stored the address - Err(n) if n == mutex => {} // Lost a race to store the same address + match self.mutex.compare_exchange(0, addr, Relaxed, Relaxed) { + Ok(_) => {} // Stored the address + Err(n) if n == addr => {} // Lost a race to store the same address _ => panic!("attempted to use a condition variable with two mutexes"), } } #[inline] pub fn notify_one(&self) { - let r = unsafe { libc::pthread_cond_signal(self.get()) }; - debug_assert_eq!(r, 0); + // SAFETY: we called `init` above. + unsafe { self.get().notify_one() } } #[inline] pub fn notify_all(&self) { - let r = unsafe { libc::pthread_cond_broadcast(self.get()) }; - debug_assert_eq!(r, 0); + // SAFETY: we called `init` above. + unsafe { self.get().notify_all() } } #[inline] pub unsafe fn wait(&self, mutex: &Mutex) { - let mutex = mutex.get_assert_locked(); + // SAFETY: the caller guarantees that the lock is owned, thus the mutex + // must have been initialized already. + let mutex = unsafe { mutex.pal.get_unchecked() }; self.verify(mutex); - let r = libc::pthread_cond_wait(self.get(), mutex); - debug_assert_eq!(r, 0); + // SAFETY: we called `init` above, we verified that this condition + // variable is only used with `mutex` and the caller guarantees that + // `mutex` is locked by the current thread. + unsafe { self.get().wait(mutex) } } - // This implementation is used on systems that support pthread_condattr_setclock - // where we configure condition variable to use monotonic clock (instead of - // default system clock). This approach avoids all problems that result - // from changes made to the system time. - #[cfg(not(any( - target_os = "android", - target_os = "espidf", - target_os = "horizon", - target_vendor = "apple", - )))] pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { - use crate::sys::time::Timespec; - - let mutex = mutex.get_assert_locked(); + // SAFETY: the caller guarantees that the lock is owned, thus the mutex + // must have been initialized already. + let mutex = unsafe { mutex.pal.get_unchecked() }; self.verify(mutex); - #[cfg(not(target_os = "nto"))] - let timeout = Timespec::now(libc::CLOCK_MONOTONIC) - .checked_add_duration(&dur) - .and_then(|t| t.to_timespec()) - .unwrap_or(TIMESPEC_MAX); - - #[cfg(target_os = "nto")] - let timeout = Timespec::now(libc::CLOCK_MONOTONIC) - .checked_add_duration(&dur) - .and_then(|t| t.to_timespec_capped()) - .unwrap_or(TIMESPEC_MAX_CAPPED); - - let r = libc::pthread_cond_timedwait(self.get(), mutex, &timeout); - assert!(r == libc::ETIMEDOUT || r == 0); - r == 0 - } - - // This implementation is modeled after libcxx's condition_variable - // https://github.com/llvm-mirror/libcxx/blob/release_35/src/condition_variable.cpp#L46 - // https://github.com/llvm-mirror/libcxx/blob/release_35/include/__mutex_base#L367 - #[cfg(any( - target_os = "android", - target_os = "espidf", - target_os = "horizon", - target_vendor = "apple", - ))] - pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { - use crate::sys::time::SystemTime; - use crate::time::Instant; - - let mutex = mutex.get_assert_locked(); - self.verify(mutex); - - // OSX implementation of `pthread_cond_timedwait` is buggy - // with super long durations. When duration is greater than - // 0x100_0000_0000_0000 seconds, `pthread_cond_timedwait` - // in macOS Sierra returns error 316. - // - // This program demonstrates the issue: - // https://gist.github.com/stepancheg/198db4623a20aad2ad7cddb8fda4a63c - // - // To work around this issue, and possible bugs of other OSes, timeout - // is clamped to 1000 years, which is allowable per the API of `wait_timeout` - // because of spurious wakeups. - let dur = Duration::min(dur, Duration::from_secs(1000 * 365 * 86400)); - - // pthread_cond_timedwait uses system time, but we want to report timeout - // based on stable time. - let now = Instant::now(); - - let timeout = SystemTime::now() - .t - .checked_add_duration(&dur) - .and_then(|t| t.to_timespec()) - .unwrap_or(TIMESPEC_MAX); - - let r = libc::pthread_cond_timedwait(self.get(), mutex, &timeout); - debug_assert!(r == libc::ETIMEDOUT || r == 0); - - // ETIMEDOUT is not a totally reliable method of determining timeout due - // to clock shifts, so do the check ourselves - now.elapsed() < dur + if pal::Condvar::PRECISE_TIMEOUT { + // SAFETY: we called `init` above, we verified that this condition + // variable is only used with `mutex` and the caller guarantees that + // `mutex` is locked by the current thread. + unsafe { self.get().wait_timeout(mutex, dur) } + } else { + // Timeout reports are not reliable, so do the check ourselves. + let now = Instant::now(); + // SAFETY: we called `init` above, we verified that this condition + // variable is only used with `mutex` and the caller guarantees that + // `mutex` is locked by the current thread. + let woken = unsafe { self.get().wait_timeout(mutex, dur) }; + woken || now.elapsed() < dur + } } } diff --git a/std/src/sys/sync/condvar/sgx.rs b/std/src/sys/sync/condvar/sgx.rs index e60715e4b592e..2bde9d0694eda 100644 --- a/std/src/sys/sync/condvar/sgx.rs +++ b/std/src/sys/sync/condvar/sgx.rs @@ -13,17 +13,19 @@ impl Condvar { } fn get(&self) -> &SpinMutex> { - self.inner.get_or_init(|| Box::new(SpinMutex::new(WaitVariable::new(())))) + self.inner.get_or_init(|| Box::pin(SpinMutex::new(WaitVariable::new(())))).get_ref() } #[inline] pub fn notify_one(&self) { - let _ = WaitQueue::notify_one(self.get().lock()); + let guard = self.get().lock(); + let _ = WaitQueue::notify_one(guard); } #[inline] pub fn notify_all(&self) { - let _ = WaitQueue::notify_all(self.get().lock()); + let guard = self.get().lock(); + let _ = WaitQueue::notify_all(guard); } pub unsafe fn wait(&self, mutex: &Mutex) { diff --git a/std/src/sys/sync/mutex/no_threads.rs b/std/src/sys/sync/mutex/no_threads.rs index 7b243575e018e..57c78f454c57c 100644 --- a/std/src/sys/sync/mutex/no_threads.rs +++ b/std/src/sys/sync/mutex/no_threads.rs @@ -10,7 +10,6 @@ unsafe impl Sync for Mutex {} // no threads on this platform impl Mutex { #[inline] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_locks", since = "1.63.0"))] pub const fn new() -> Mutex { Mutex { locked: Cell::new(false) } } diff --git a/std/src/sys/sync/mutex/pthread.rs b/std/src/sys/sync/mutex/pthread.rs index abd58122523cf..75b4b9c6dad9b 100644 --- a/std/src/sys/sync/mutex/pthread.rs +++ b/std/src/sys/sync/mutex/pthread.rs @@ -1,163 +1,66 @@ -use crate::cell::UnsafeCell; -use crate::io::Error; -use crate::mem::{MaybeUninit, forget}; -use crate::sys::cvt_nz; -use crate::sys::sync::OnceBox; +#![forbid(unsafe_op_in_unsafe_fn)] -struct AllocatedMutex(UnsafeCell); +use crate::mem::forget; +use crate::pin::Pin; +use crate::sys::pal::sync as pal; +use crate::sys::sync::OnceBox; pub struct Mutex { - inner: OnceBox, -} - -unsafe impl Send for AllocatedMutex {} -unsafe impl Sync for AllocatedMutex {} - -impl AllocatedMutex { - fn new() -> Box { - let mutex = Box::new(AllocatedMutex(UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER))); - - // Issue #33770 - // - // A pthread mutex initialized with PTHREAD_MUTEX_INITIALIZER will have - // a type of PTHREAD_MUTEX_DEFAULT, which has undefined behavior if you - // try to re-lock it from the same thread when you already hold a lock - // (https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_init.html). - // This is the case even if PTHREAD_MUTEX_DEFAULT == PTHREAD_MUTEX_NORMAL - // (https://github.com/rust-lang/rust/issues/33770#issuecomment-220847521) -- in that - // case, `pthread_mutexattr_settype(PTHREAD_MUTEX_DEFAULT)` will of course be the same - // as setting it to `PTHREAD_MUTEX_NORMAL`, but not setting any mode will result in - // a Mutex where re-locking is UB. - // - // In practice, glibc takes advantage of this undefined behavior to - // implement hardware lock elision, which uses hardware transactional - // memory to avoid acquiring the lock. While a transaction is in - // progress, the lock appears to be unlocked. This isn't a problem for - // other threads since the transactional memory will abort if a conflict - // is detected, however no abort is generated when re-locking from the - // same thread. - // - // Since locking the same mutex twice will result in two aliasing &mut - // references, we instead create the mutex with type - // PTHREAD_MUTEX_NORMAL which is guaranteed to deadlock if we try to - // re-lock it from the same thread, thus avoiding undefined behavior. - unsafe { - let mut attr = MaybeUninit::::uninit(); - cvt_nz(libc::pthread_mutexattr_init(attr.as_mut_ptr())).unwrap(); - let attr = PthreadMutexAttr(&mut attr); - cvt_nz(libc::pthread_mutexattr_settype( - attr.0.as_mut_ptr(), - libc::PTHREAD_MUTEX_NORMAL, - )) - .unwrap(); - cvt_nz(libc::pthread_mutex_init(mutex.0.get(), attr.0.as_ptr())).unwrap(); - } - - mutex - } -} - -impl Drop for AllocatedMutex { - #[inline] - fn drop(&mut self) { - let r = unsafe { libc::pthread_mutex_destroy(self.0.get()) }; - if cfg!(target_os = "dragonfly") { - // On DragonFly pthread_mutex_destroy() returns EINVAL if called on a - // mutex that was just initialized with libc::PTHREAD_MUTEX_INITIALIZER. - // Once it is used (locked/unlocked) or pthread_mutex_init() is called, - // this behavior no longer occurs. - debug_assert!(r == 0 || r == libc::EINVAL); - } else { - debug_assert_eq!(r, 0); - } - } + pub pal: OnceBox, } impl Mutex { #[inline] pub const fn new() -> Mutex { - Mutex { inner: OnceBox::new() } + Mutex { pal: OnceBox::new() } } - /// Gets access to the pthread mutex under the assumption that the mutex is - /// locked. - /// - /// This allows skipping the initialization check, as the mutex can only be - /// locked if it is already initialized, and allows relaxing the ordering - /// on the pointer load, since the allocation cannot have been modified - /// since the `lock` and the lock must have occurred on the current thread. - /// - /// # Safety - /// Causes undefined behavior if the mutex is not locked. #[inline] - pub(crate) unsafe fn get_assert_locked(&self) -> *mut libc::pthread_mutex_t { - unsafe { self.inner.get_unchecked().0.get() } - } - - #[inline] - fn get(&self) -> *mut libc::pthread_mutex_t { - // If initialization fails, the mutex is destroyed. This is always sound, - // however, as the mutex cannot have been locked yet. - self.inner.get_or_init(AllocatedMutex::new).0.get() + fn get(&self) -> Pin<&pal::Mutex> { + // If the initialization race is lost, the new mutex is destroyed. + // This is sound however, as it cannot have been locked. + self.pal.get_or_init(|| { + let mut pal = Box::pin(pal::Mutex::new()); + // SAFETY: we only call `init` once per `pal::Mutex`, namely here. + unsafe { pal.as_mut().init() }; + pal + }) } #[inline] pub fn lock(&self) { - #[cold] - #[inline(never)] - fn fail(r: i32) -> ! { - let error = Error::from_raw_os_error(r); - panic!("failed to lock mutex: {error}"); - } - - let r = unsafe { libc::pthread_mutex_lock(self.get()) }; - // As we set the mutex type to `PTHREAD_MUTEX_NORMAL` above, we expect - // the lock call to never fail. Unfortunately however, some platforms - // (Solaris) do not conform to the standard, and instead always provide - // deadlock detection. How kind of them! Unfortunately that means that - // we need to check the error code here. To save us from UB on other - // less well-behaved platforms in the future, we do it even on "good" - // platforms like macOS. See #120147 for more context. - if r != 0 { - fail(r) - } + // SAFETY: we call `init` above, therefore reentrant locking is safe. + // In `drop` we ensure that the mutex is not destroyed while locked. + unsafe { self.get().lock() } } #[inline] pub unsafe fn unlock(&self) { - let r = libc::pthread_mutex_unlock(self.get_assert_locked()); - debug_assert_eq!(r, 0); + // SAFETY: the mutex can only be locked if it is already initialized + // and we observed this initialization since we observed the locking. + unsafe { self.pal.get_unchecked().unlock() } } #[inline] pub fn try_lock(&self) -> bool { - unsafe { libc::pthread_mutex_trylock(self.get()) == 0 } + // SAFETY: we call `init` above, therefore reentrant locking is safe. + // In `drop` we ensure that the mutex is not destroyed while locked. + unsafe { self.get().try_lock() } } } impl Drop for Mutex { fn drop(&mut self) { - let Some(mutex) = self.inner.take() else { return }; + let Some(pal) = self.pal.take() else { return }; // We're not allowed to pthread_mutex_destroy a locked mutex, // so check first if it's unlocked. - if unsafe { libc::pthread_mutex_trylock(mutex.0.get()) == 0 } { - unsafe { libc::pthread_mutex_unlock(mutex.0.get()) }; - drop(mutex); + if unsafe { pal.as_ref().try_lock() } { + unsafe { pal.as_ref().unlock() }; + drop(pal) } else { // The mutex is locked. This happens if a MutexGuard is leaked. // In this case, we just leak the Mutex too. - forget(mutex); - } - } -} - -pub(super) struct PthreadMutexAttr<'a>(pub &'a mut MaybeUninit); - -impl Drop for PthreadMutexAttr<'_> { - fn drop(&mut self) { - unsafe { - let result = libc::pthread_mutexattr_destroy(self.0.as_mut_ptr()); - debug_assert_eq!(result, 0); + forget(pal) } } } diff --git a/std/src/sys/sync/mutex/sgx.rs b/std/src/sys/sync/mutex/sgx.rs index 8529e85797043..3eb981bc65af6 100644 --- a/std/src/sys/sync/mutex/sgx.rs +++ b/std/src/sys/sync/mutex/sgx.rs @@ -13,7 +13,7 @@ impl Mutex { } fn get(&self) -> &SpinMutex> { - self.inner.get_or_init(|| Box::new(SpinMutex::new(WaitVariable::new(false)))) + self.inner.get_or_init(|| Box::pin(SpinMutex::new(WaitVariable::new(false)))).get_ref() } #[inline] @@ -33,7 +33,7 @@ impl Mutex { pub unsafe fn unlock(&self) { // SAFETY: the mutex was locked by the current thread, so it has been // initialized already. - let guard = unsafe { self.inner.get_unchecked().lock() }; + let guard = unsafe { self.inner.get_unchecked().get_ref().lock() }; if let Err(mut guard) = WaitQueue::notify_one(guard) { // No other waiters, unlock *guard.lock_var_mut() = false; diff --git a/std/src/sys/sync/once/futex.rs b/std/src/sys/sync/once/futex.rs index 10bfa81a6d72a..539f0fe89eaaa 100644 --- a/std/src/sys/sync/once/futex.rs +++ b/std/src/sys/sync/once/futex.rs @@ -1,7 +1,7 @@ use crate::cell::Cell; use crate::sync as public; use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release}; -use crate::sync::once::ExclusiveState; +use crate::sync::poison::once::ExclusiveState; use crate::sys::futex::{Futex, Primitive, futex_wait, futex_wake_all}; // On some platforms, the OS is very nice and handles the waiter queue for us. diff --git a/std/src/sys/sync/once/no_threads.rs b/std/src/sys/sync/once/no_threads.rs index fb1b496510aba..2568059cfe3a8 100644 --- a/std/src/sys/sync/once/no_threads.rs +++ b/std/src/sys/sync/once/no_threads.rs @@ -1,6 +1,6 @@ use crate::cell::Cell; use crate::sync as public; -use crate::sync::once::ExclusiveState; +use crate::sync::poison::once::ExclusiveState; pub struct Once { state: Cell, @@ -35,7 +35,6 @@ unsafe impl Sync for Once {} impl Once { #[inline] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_once_new", since = "1.32.0"))] pub const fn new() -> Once { Once { state: Cell::new(State::Incomplete) } } diff --git a/std/src/sys/sync/once/queue.rs b/std/src/sys/sync/once/queue.rs index 87837915b396e..fde1e0ca51029 100644 --- a/std/src/sys/sync/once/queue.rs +++ b/std/src/sys/sync/once/queue.rs @@ -58,7 +58,7 @@ use crate::cell::Cell; use crate::sync::atomic::Ordering::{AcqRel, Acquire, Release}; use crate::sync::atomic::{AtomicBool, AtomicPtr}; -use crate::sync::once::ExclusiveState; +use crate::sync::poison::once::ExclusiveState; use crate::thread::{self, Thread}; use crate::{fmt, ptr, sync as public}; @@ -116,7 +116,6 @@ fn to_state(current: StateAndQueue) -> usize { impl Once { #[inline] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_once_new", since = "1.32.0"))] pub const fn new() -> Once { Once { state_and_queue: AtomicPtr::new(ptr::without_provenance_mut(INCOMPLETE)) } } diff --git a/std/src/sys/sync/once_box.rs b/std/src/sys/sync/once_box.rs index 4105af503295f..6953b91999ad1 100644 --- a/std/src/sys/sync/once_box.rs +++ b/std/src/sys/sync/once_box.rs @@ -6,6 +6,7 @@ #![allow(dead_code)] // Only used on some platforms. use crate::mem::replace; +use crate::pin::Pin; use crate::ptr::null_mut; use crate::sync::atomic::AtomicPtr; use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release}; @@ -27,46 +28,46 @@ impl OnceBox { /// pointer load in this function can be performed with relaxed ordering, /// potentially allowing the optimizer to turn code like this: /// ```rust, ignore - /// once_box.get_or_init(|| Box::new(42)); + /// once_box.get_or_init(|| Box::pin(42)); /// unsafe { once_box.get_unchecked() } /// ``` /// into /// ```rust, ignore - /// once_box.get_or_init(|| Box::new(42)) + /// once_box.get_or_init(|| Box::pin(42)) /// ``` /// /// # Safety /// This causes undefined behavior if the assumption above is violated. #[inline] - pub unsafe fn get_unchecked(&self) -> &T { - unsafe { &*self.ptr.load(Relaxed) } + pub unsafe fn get_unchecked(&self) -> Pin<&T> { + unsafe { Pin::new_unchecked(&*self.ptr.load(Relaxed)) } } #[inline] - pub fn get_or_init(&self, f: impl FnOnce() -> Box) -> &T { + pub fn get_or_init(&self, f: impl FnOnce() -> Pin>) -> Pin<&T> { let ptr = self.ptr.load(Acquire); match unsafe { ptr.as_ref() } { - Some(val) => val, + Some(val) => unsafe { Pin::new_unchecked(val) }, None => self.initialize(f), } } #[inline] - pub fn take(&mut self) -> Option> { + pub fn take(&mut self) -> Option>> { let ptr = replace(self.ptr.get_mut(), null_mut()); - if !ptr.is_null() { Some(unsafe { Box::from_raw(ptr) }) } else { None } + if !ptr.is_null() { Some(unsafe { Pin::new_unchecked(Box::from_raw(ptr)) }) } else { None } } #[cold] - fn initialize(&self, f: impl FnOnce() -> Box) -> &T { - let new_ptr = Box::into_raw(f()); + fn initialize(&self, f: impl FnOnce() -> Pin>) -> Pin<&T> { + let new_ptr = Box::into_raw(unsafe { Pin::into_inner_unchecked(f()) }); match self.ptr.compare_exchange(null_mut(), new_ptr, Release, Acquire) { - Ok(_) => unsafe { &*new_ptr }, + Ok(_) => unsafe { Pin::new_unchecked(&*new_ptr) }, Err(ptr) => { // Lost the race to another thread. // Drop the value we created, and use the one from the other thread instead. drop(unsafe { Box::from_raw(new_ptr) }); - unsafe { &*ptr } + unsafe { Pin::new_unchecked(&*ptr) } } } } diff --git a/std/src/sys/sync/rwlock/no_threads.rs b/std/src/sys/sync/rwlock/no_threads.rs index c11e59f719e93..573d0d602dbd6 100644 --- a/std/src/sys/sync/rwlock/no_threads.rs +++ b/std/src/sys/sync/rwlock/no_threads.rs @@ -10,7 +10,6 @@ unsafe impl Sync for RwLock {} // no threads on this platform impl RwLock { #[inline] - #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_locks", since = "1.63.0"))] pub const fn new() -> RwLock { RwLock { mode: Cell::new(0) } } diff --git a/std/src/sys/sync/thread_parking/pthread.rs b/std/src/sys/sync/thread_parking/pthread.rs index 76df73b2a8e06..19cabd7dd75c8 100644 --- a/std/src/sys/sync/thread_parking/pthread.rs +++ b/std/src/sys/sync/thread_parking/pthread.rs @@ -1,93 +1,19 @@ //! Thread parking without `futex` using the `pthread` synchronization primitives. -use crate::cell::UnsafeCell; -use crate::marker::PhantomPinned; use crate::pin::Pin; use crate::sync::atomic::AtomicUsize; use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release}; -#[cfg(not(target_os = "nto"))] -use crate::sys::time::TIMESPEC_MAX; -#[cfg(target_os = "nto")] -use crate::sys::time::TIMESPEC_MAX_CAPPED; +use crate::sys::pal::sync::{Condvar, Mutex}; use crate::time::Duration; const EMPTY: usize = 0; const PARKED: usize = 1; const NOTIFIED: usize = 2; -unsafe fn lock(lock: *mut libc::pthread_mutex_t) { - let r = libc::pthread_mutex_lock(lock); - debug_assert_eq!(r, 0); -} - -unsafe fn unlock(lock: *mut libc::pthread_mutex_t) { - let r = libc::pthread_mutex_unlock(lock); - debug_assert_eq!(r, 0); -} - -unsafe fn notify_one(cond: *mut libc::pthread_cond_t) { - let r = libc::pthread_cond_signal(cond); - debug_assert_eq!(r, 0); -} - -unsafe fn wait(cond: *mut libc::pthread_cond_t, lock: *mut libc::pthread_mutex_t) { - let r = libc::pthread_cond_wait(cond, lock); - debug_assert_eq!(r, 0); -} - -unsafe fn wait_timeout( - cond: *mut libc::pthread_cond_t, - lock: *mut libc::pthread_mutex_t, - dur: Duration, -) { - // Use the system clock on systems that do not support pthread_condattr_setclock. - // This unfortunately results in problems when the system time changes. - #[cfg(any(target_os = "espidf", target_os = "horizon", target_vendor = "apple"))] - let (now, dur) = { - use crate::cmp::min; - use crate::sys::time::SystemTime; - - // OSX implementation of `pthread_cond_timedwait` is buggy - // with super long durations. When duration is greater than - // 0x100_0000_0000_0000 seconds, `pthread_cond_timedwait` - // in macOS Sierra return error 316. - // - // This program demonstrates the issue: - // https://gist.github.com/stepancheg/198db4623a20aad2ad7cddb8fda4a63c - // - // To work around this issue, and possible bugs of other OSes, timeout - // is clamped to 1000 years, which is allowable per the API of `park_timeout` - // because of spurious wakeups. - let dur = min(dur, Duration::from_secs(1000 * 365 * 86400)); - let now = SystemTime::now().t; - (now, dur) - }; - // Use the monotonic clock on other systems. - #[cfg(not(any(target_os = "espidf", target_os = "horizon", target_vendor = "apple")))] - let (now, dur) = { - use crate::sys::time::Timespec; - - (Timespec::now(libc::CLOCK_MONOTONIC), dur) - }; - - #[cfg(not(target_os = "nto"))] - let timeout = - now.checked_add_duration(&dur).and_then(|t| t.to_timespec()).unwrap_or(TIMESPEC_MAX); - #[cfg(target_os = "nto")] - let timeout = now - .checked_add_duration(&dur) - .and_then(|t| t.to_timespec_capped()) - .unwrap_or(TIMESPEC_MAX_CAPPED); - let r = libc::pthread_cond_timedwait(cond, lock, &timeout); - debug_assert!(r == libc::ETIMEDOUT || r == 0); -} - pub struct Parker { state: AtomicUsize, - lock: UnsafeCell, - cvar: UnsafeCell, - // The `pthread` primitives require a stable address, so make this struct `!Unpin`. - _pinned: PhantomPinned, + lock: Mutex, + cvar: Condvar, } impl Parker { @@ -96,38 +22,21 @@ impl Parker { /// # Safety /// The constructed parker must never be moved. pub unsafe fn new_in_place(parker: *mut Parker) { - // Use the default mutex implementation to allow for simpler initialization. - // This could lead to undefined behavior when deadlocking. This is avoided - // by not deadlocking. Note in particular the unlocking operation before any - // panic, as code after the panic could try to park again. - (&raw mut (*parker).state).write(AtomicUsize::new(EMPTY)); - (&raw mut (*parker).lock).write(UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER)); + parker.write(Parker { + state: AtomicUsize::new(EMPTY), + lock: Mutex::new(), + cvar: Condvar::new(), + }); - cfg_if::cfg_if! { - if #[cfg(any( - target_os = "l4re", - target_os = "android", - target_os = "redox", - target_os = "vita", - target_vendor = "apple", - ))] { - (&raw mut (*parker).cvar).write(UnsafeCell::new(libc::PTHREAD_COND_INITIALIZER)); - } else if #[cfg(any(target_os = "espidf", target_os = "horizon"))] { - let r = libc::pthread_cond_init((&raw mut (*parker).cvar).cast(), crate::ptr::null()); - assert_eq!(r, 0); - } else { - use crate::mem::MaybeUninit; - let mut attr = MaybeUninit::::uninit(); - let r = libc::pthread_condattr_init(attr.as_mut_ptr()); - assert_eq!(r, 0); - let r = libc::pthread_condattr_setclock(attr.as_mut_ptr(), libc::CLOCK_MONOTONIC); - assert_eq!(r, 0); - let r = libc::pthread_cond_init((&raw mut (*parker).cvar).cast(), attr.as_ptr()); - assert_eq!(r, 0); - let r = libc::pthread_condattr_destroy(attr.as_mut_ptr()); - assert_eq!(r, 0); - } - } + Pin::new_unchecked(&mut (*parker).cvar).init(); + } + + fn lock(self: Pin<&Self>) -> Pin<&Mutex> { + unsafe { self.map_unchecked(|p| &p.lock) } + } + + fn cvar(self: Pin<&Self>) -> Pin<&Condvar> { + unsafe { self.map_unchecked(|p| &p.cvar) } } // This implementation doesn't require `unsafe`, but other implementations @@ -142,7 +51,7 @@ impl Parker { } // Otherwise we need to coordinate going to sleep - lock(self.lock.get()); + self.lock().lock(); match self.state.compare_exchange(EMPTY, PARKED, Relaxed, Relaxed) { Ok(_) => {} Err(NOTIFIED) => { @@ -154,20 +63,20 @@ impl Parker { // read from the write it made to `state`. let old = self.state.swap(EMPTY, Acquire); - unlock(self.lock.get()); + self.lock().unlock(); assert_eq!(old, NOTIFIED, "park state changed unexpectedly"); return; } // should consume this notification, so prohibit spurious wakeups in next park. Err(_) => { - unlock(self.lock.get()); + self.lock().unlock(); panic!("inconsistent park state") } } loop { - wait(self.cvar.get(), self.lock.get()); + self.cvar().wait(self.lock()); match self.state.compare_exchange(NOTIFIED, EMPTY, Acquire, Relaxed) { Ok(_) => break, // got a notification @@ -175,7 +84,7 @@ impl Parker { } } - unlock(self.lock.get()); + self.lock().unlock(); } // This implementation doesn't require `unsafe`, but other implementations @@ -189,19 +98,19 @@ impl Parker { return; } - lock(self.lock.get()); + self.lock().lock(); match self.state.compare_exchange(EMPTY, PARKED, Relaxed, Relaxed) { Ok(_) => {} Err(NOTIFIED) => { // We must read again here, see `park`. let old = self.state.swap(EMPTY, Acquire); - unlock(self.lock.get()); + self.lock().unlock(); assert_eq!(old, NOTIFIED, "park state changed unexpectedly"); return; } // should consume this notification, so prohibit spurious wakeups in next park. Err(_) => { - unlock(self.lock.get()); + self.lock().unlock(); panic!("inconsistent park_timeout state") } } @@ -210,13 +119,13 @@ impl Parker { // from a notification we just want to unconditionally set the state back to // empty, either consuming a notification or un-flagging ourselves as // parked. - wait_timeout(self.cvar.get(), self.lock.get(), dur); + self.cvar().wait_timeout(self.lock(), dur); match self.state.swap(EMPTY, Acquire) { - NOTIFIED => unlock(self.lock.get()), // got a notification, hurray! - PARKED => unlock(self.lock.get()), // no notification, alas + NOTIFIED => self.lock().unlock(), // got a notification, hurray! + PARKED => self.lock().unlock(), // no notification, alas n => { - unlock(self.lock.get()); + self.lock().unlock(); panic!("inconsistent park_timeout state: {n}") } } @@ -248,21 +157,9 @@ impl Parker { // parked thread wakes it doesn't get woken only to have to wait for us // to release `lock`. unsafe { - lock(self.lock.get()); - unlock(self.lock.get()); - notify_one(self.cvar.get()); + self.lock().lock(); + self.lock().unlock(); + self.cvar().notify_one(); } } } - -impl Drop for Parker { - fn drop(&mut self) { - unsafe { - libc::pthread_cond_destroy(self.cvar.get_mut()); - libc::pthread_mutex_destroy(self.lock.get_mut()); - } - } -} - -unsafe impl Sync for Parker {} -unsafe impl Send for Parker {} diff --git a/std/src/sys/thread_local/key/racy.rs b/std/src/sys/thread_local/key/racy.rs index 97df8997b80de..e1bc08eabb358 100644 --- a/std/src/sys/thread_local/key/racy.rs +++ b/std/src/sys/thread_local/key/racy.rs @@ -30,7 +30,6 @@ const KEY_SENTVAL: usize = 0; const KEY_SENTVAL: usize = libc::PTHREAD_KEYS_MAX + 1; impl LazyKey { - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "thread_local_internals", issue = "none"))] pub const fn new(dtor: Option) -> LazyKey { LazyKey { key: atomic::AtomicUsize::new(KEY_SENTVAL), dtor } } diff --git a/std/src/sys/thread_local/key/unix.rs b/std/src/sys/thread_local/key/unix.rs index 28e48a750b9bf..b4b58b3470631 100644 --- a/std/src/sys/thread_local/key/unix.rs +++ b/std/src/sys/thread_local/key/unix.rs @@ -1,5 +1,25 @@ use crate::mem; +// For WASI add a few symbols not in upstream `libc` just yet. +#[cfg(all(target_os = "wasi", target_env = "p1", target_feature = "atomics"))] +mod libc { + use crate::ffi; + + #[allow(non_camel_case_types)] + pub type pthread_key_t = ffi::c_uint; + + extern "C" { + pub fn pthread_key_create( + key: *mut pthread_key_t, + destructor: unsafe extern "C" fn(*mut ffi::c_void), + ) -> ffi::c_int; + #[allow(dead_code)] + pub fn pthread_getspecific(key: pthread_key_t) -> *mut ffi::c_void; + pub fn pthread_setspecific(key: pthread_key_t, value: *const ffi::c_void) -> ffi::c_int; + pub fn pthread_key_delete(key: pthread_key_t) -> ffi::c_int; + } +} + pub type Key = libc::pthread_key_t; #[inline] diff --git a/std/src/sys/thread_local/mod.rs b/std/src/sys/thread_local/mod.rs index 31d3b43906004..f0a13323ec93f 100644 --- a/std/src/sys/thread_local/mod.rs +++ b/std/src/sys/thread_local/mod.rs @@ -86,7 +86,9 @@ pub(crate) mod guard { mod windows; pub(crate) use windows::enable; } else if #[cfg(any( - target_family = "wasm", + all(target_family = "wasm", not( + all(target_os = "wasi", target_env = "p1", target_feature = "atomics") + )), target_os = "uefi", target_os = "zkvm", ))] { @@ -135,6 +137,7 @@ pub(crate) mod key { target_family = "unix", ), target_os = "teeos", + all(target_os = "wasi", target_env = "p1", target_feature = "atomics"), ))] { mod racy; mod unix; diff --git a/std/src/sys/thread_local/os.rs b/std/src/sys/thread_local/os.rs index 58f291ffdb985..00d2e30bd6036 100644 --- a/std/src/sys/thread_local/os.rs +++ b/std/src/sys/thread_local/os.rs @@ -60,7 +60,6 @@ struct Value { } impl Storage { - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "thread_local_internals", issue = "none"))] pub const fn new() -> Storage { Storage { key: LazyKey::new(Some(destroy_value::)), marker: PhantomData } } diff --git a/std/src/sys_common/fs.rs b/std/src/sys_common/fs.rs index a25a7244660bb..bfd684d295b89 100644 --- a/std/src/sys_common/fs.rs +++ b/std/src/sys_common/fs.rs @@ -5,7 +5,7 @@ use crate::io::{self, Error, ErrorKind}; use crate::path::Path; use crate::sys_common::ignore_notfound; -pub(crate) const NOT_FILE_ERROR: Error = io::const_io_error!( +pub(crate) const NOT_FILE_ERROR: Error = io::const_error!( ErrorKind::InvalidInput, "the source path is neither a regular file nor a symlink to a regular file", ); diff --git a/std/src/sys_common/net.rs b/std/src/sys_common/net.rs index 5a0ad90758101..74306978d2284 100644 --- a/std/src/sys_common/net.rs +++ b/std/src/sys_common/net.rs @@ -122,7 +122,7 @@ pub fn sockaddr_to_addr(storage: &c::sockaddr_storage, len: usize) -> io::Result *(storage as *const _ as *const c::sockaddr_in6) }))) } - _ => Err(io::const_io_error!(ErrorKind::InvalidInput, "invalid argument")), + _ => Err(io::const_error!(ErrorKind::InvalidInput, "invalid argument")), } } @@ -185,7 +185,7 @@ impl TryFrom<&str> for LookupHost { ($e:expr, $msg:expr) => { match $e { Some(r) => r, - None => return Err(io::const_io_error!(io::ErrorKind::InvalidInput, $msg)), + None => return Err(io::const_error!(io::ErrorKind::InvalidInput, $msg)), } }; } diff --git a/std/src/sys_common/process.rs b/std/src/sys_common/process.rs index 5333ee146f7d6..9f61d69d85875 100644 --- a/std/src/sys_common/process.rs +++ b/std/src/sys_common/process.rs @@ -8,19 +8,13 @@ use crate::sys::process::{EnvKey, ExitStatus, Process, StdioPipes}; use crate::{env, fmt, io}; // Stores a set of changes to an environment -#[derive(Clone)] +#[derive(Clone, Default)] pub struct CommandEnv { clear: bool, saw_path: bool, vars: BTreeMap>, } -impl Default for CommandEnv { - fn default() -> Self { - CommandEnv { clear: false, saw_path: false, vars: Default::default() } - } -} - impl fmt::Debug for CommandEnv { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut debug_command_env = f.debug_struct("CommandEnv"); diff --git a/std/src/sys_common/wtf8.rs b/std/src/sys_common/wtf8.rs index 666942bb8a10f..6c60d901ee904 100644 --- a/std/src/sys_common/wtf8.rs +++ b/std/src/sys_common/wtf8.rs @@ -204,8 +204,8 @@ impl Wtf8Buf { /// /// Since WTF-8 is a superset of UTF-8, this always succeeds. #[inline] - pub fn from_str(str: &str) -> Wtf8Buf { - Wtf8Buf { bytes: <[_]>::to_vec(str.as_bytes()), is_known_utf8: true } + pub fn from_str(s: &str) -> Wtf8Buf { + Wtf8Buf { bytes: <[_]>::to_vec(s.as_bytes()), is_known_utf8: true } } pub fn clear(&mut self) { diff --git a/std/src/thread/current.rs b/std/src/thread/current.rs index b9b959f98946b..414711298f047 100644 --- a/std/src/thread/current.rs +++ b/std/src/thread/current.rs @@ -15,7 +15,7 @@ local_pointer! { /// /// We store the thread ID so that it never gets destroyed during the lifetime /// of a thread, either using `#[thread_local]` or multiple `local_pointer!`s. -mod id { +pub(super) mod id { use super::*; cfg_if::cfg_if! { @@ -27,7 +27,7 @@ mod id { pub(super) const CHEAP: bool = true; - pub(super) fn get() -> Option { + pub(crate) fn get() -> Option { ID.get() } @@ -44,7 +44,7 @@ mod id { pub(super) const CHEAP: bool = false; - pub(super) fn get() -> Option { + pub(crate) fn get() -> Option { let id0 = ID0.get().addr() as u64; let id16 = ID16.get().addr() as u64; let id32 = ID32.get().addr() as u64; @@ -67,7 +67,7 @@ mod id { pub(super) const CHEAP: bool = false; - pub(super) fn get() -> Option { + pub(crate) fn get() -> Option { let id0 = ID0.get().addr() as u64; let id32 = ID32.get().addr() as u64; ThreadId::from_u64((id32 << 32) + id0) @@ -85,7 +85,7 @@ mod id { pub(super) const CHEAP: bool = true; - pub(super) fn get() -> Option { + pub(crate) fn get() -> Option { let id = ID.get().addr() as u64; ThreadId::from_u64(id) } @@ -112,7 +112,7 @@ mod id { /// Tries to set the thread handle for the current thread. Fails if a handle was /// already set or if the thread ID of `thread` would change an already-set ID. -pub(crate) fn set_current(thread: Thread) -> Result<(), Thread> { +pub(super) fn set_current(thread: Thread) -> Result<(), Thread> { if CURRENT.get() != NONE { return Err(thread); } @@ -136,32 +136,35 @@ pub(crate) fn set_current(thread: Thread) -> Result<(), Thread> { /// one thread and is guaranteed not to call the global allocator. #[inline] pub(crate) fn current_id() -> ThreadId { - // If accessing the persistant thread ID takes multiple TLS accesses, try + // If accessing the persistent thread ID takes multiple TLS accesses, try // to retrieve it from the current thread handle, which will only take one // TLS access. if !id::CHEAP { - let current = CURRENT.get(); - if current > DESTROYED { - unsafe { - let current = ManuallyDrop::new(Thread::from_raw(current)); - return current.id(); - } + if let Some(id) = try_with_current(|t| t.map(|t| t.id())) { + return id; } } id::get_or_init() } -/// Gets a handle to the thread that invokes it, if the handle has been initialized. -pub(crate) fn try_current() -> Option { +/// Gets a reference to the handle of the thread that invokes it, if the handle +/// has been initialized. +pub(super) fn try_with_current(f: F) -> R +where + F: FnOnce(Option<&Thread>) -> R, +{ let current = CURRENT.get(); if current > DESTROYED { + // SAFETY: `Arc` does not contain interior mutability, so it does not + // matter that the address of the handle might be different depending + // on where this is called. unsafe { let current = ManuallyDrop::new(Thread::from_raw(current)); - Some((*current).clone()) + f(Some(¤t)) } } else { - None + f(None) } } @@ -176,7 +179,7 @@ pub(crate) fn current_or_unnamed() -> Thread { (*current).clone() } } else if current == DESTROYED { - Thread::new_unnamed(id::get_or_init()) + Thread::new(id::get_or_init(), None) } else { init_current(current) } @@ -221,7 +224,7 @@ fn init_current(current: *mut ()) -> Thread { CURRENT.set(BUSY); // If the thread ID was initialized already, use it. let id = id::get_or_init(); - let thread = Thread::new_unnamed(id); + let thread = Thread::new(id, None); // Make sure that `crate::rt::thread_cleanup` will be run, which will // call `drop_current`. @@ -243,17 +246,17 @@ fn init_current(current: *mut ()) -> Thread { // a particular API should be entirely allocation-free, feel free to open // an issue on the Rust repository, we'll see what we can do. rtabort!( - "\n - Attempted to access thread-local data while allocating said data.\n - Do not access functions that allocate in the global allocator!\n - This is a bug in the global allocator.\n - " + "\n\ + Attempted to access thread-local data while allocating said data.\n\ + Do not access functions that allocate in the global allocator!\n\ + This is a bug in the global allocator.\n\ + " ) } else { debug_assert_eq!(current, DESTROYED); panic!( - "use of std::thread::current() is not possible after the thread's - local data has been destroyed" + "use of std::thread::current() is not possible after the thread's \ + local data has been destroyed" ) } } diff --git a/std/src/thread/local.rs b/std/src/thread/local.rs index 9edb3fa41933d..2313f4b5beb11 100644 --- a/std/src/thread/local.rs +++ b/std/src/thread/local.rs @@ -12,7 +12,7 @@ use crate::cell::{Cell, RefCell}; use crate::error::Error; use crate::fmt; -/// A thread local storage key which owns its contents. +/// A thread local storage (TLS) key which owns its contents. /// /// This key uses the fastest possible implementation available to it for the /// target platform. It is instantiated with the [`thread_local!`] macro and the @@ -237,7 +237,6 @@ impl LocalKey { reason = "recently added to create a key", issue = "none" )] - #[cfg_attr(bootstrap, rustc_const_unstable(feature = "thread_local_internals", issue = "none"))] pub const unsafe fn new(inner: fn(Option<&mut Option>) -> *const T) -> LocalKey { LocalKey { inner } } @@ -252,6 +251,19 @@ impl LocalKey { /// This function will `panic!()` if the key currently has its /// destructor running, and it **may** panic if the destructor has /// previously been run for this thread. + /// + /// # Examples + /// + /// ``` + /// thread_local! { + /// pub static STATIC: String = String::from("I am"); + /// } + /// + /// assert_eq!( + /// STATIC.with(|original_value| format!("{original_value} initialized")), + /// "I am initialized", + /// ); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn with(&'static self, f: F) -> R where @@ -273,6 +285,19 @@ impl LocalKey { /// /// This function will still `panic!()` if the key is uninitialized and the /// key's initializer panics. + /// + /// # Examples + /// + /// ``` + /// thread_local! { + /// pub static STATIC: String = String::from("I am"); + /// } + /// + /// assert_eq!( + /// STATIC.try_with(|original_value| format!("{original_value} initialized")), + /// Ok(String::from("I am initialized")), + /// ); + /// ``` #[stable(feature = "thread_local_try_with", since = "1.26.0")] #[inline] pub fn try_with(&'static self, f: F) -> Result @@ -452,7 +477,7 @@ impl LocalKey> { /// Panics if the key currently has its destructor running, /// and it **may** panic if the destructor has previously been run for this thread. /// - /// # Example + /// # Examples /// /// ``` /// use std::cell::RefCell; @@ -483,7 +508,7 @@ impl LocalKey> { /// Panics if the key currently has its destructor running, /// and it **may** panic if the destructor has previously been run for this thread. /// - /// # Example + /// # Examples /// /// ``` /// use std::cell::RefCell; diff --git a/std/src/thread/mod.rs b/std/src/thread/mod.rs index 2ff44fcd4c6b7..59b395336f2e3 100644 --- a/std/src/thread/mod.rs +++ b/std/src/thread/mod.rs @@ -158,12 +158,9 @@ #[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))] mod tests; -use core::cell::SyncUnsafeCell; -use core::ffi::CStr; -use core::mem::MaybeUninit; - use crate::any::Any; use crate::cell::UnsafeCell; +use crate::ffi::CStr; use crate::marker::PhantomData; use crate::mem::{self, ManuallyDrop, forget}; use crate::num::NonZero; @@ -186,7 +183,8 @@ mod current; #[stable(feature = "rust1", since = "1.0.0")] pub use current::current; -pub(crate) use current::{current_id, current_or_unnamed, drop_current, set_current, try_current}; +pub(crate) use current::{current_id, current_or_unnamed, drop_current}; +use current::{set_current, try_with_current}; mod spawnhook; @@ -391,6 +389,7 @@ impl Builder { /// handler.join().unwrap(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub fn spawn(self, f: F) -> io::Result> where F: FnOnce() -> T, @@ -458,6 +457,7 @@ impl Builder { /// /// [`io::Result`]: crate::io::Result #[stable(feature = "thread_spawn_unchecked", since = "1.82.0")] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub unsafe fn spawn_unchecked(self, f: F) -> io::Result> where F: FnOnce() -> T, @@ -467,6 +467,7 @@ impl Builder { Ok(JoinHandle(unsafe { self.spawn_unchecked_(f, None) }?)) } + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces unsafe fn spawn_unchecked_<'scope, F, T>( self, f: F, @@ -498,10 +499,7 @@ impl Builder { }); let id = ThreadId::new(); - let my_thread = match name { - Some(name) => Thread::new(id, name.into()), - None => Thread::new_unnamed(id), - }; + let my_thread = Thread::new(id, name); let hooks = if no_hooks { spawnhook::ChildSpawnHooks::default() @@ -721,6 +719,7 @@ impl Builder { /// [`join`]: JoinHandle::join /// [`Err`]: crate::result::Result::Err #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub fn spawn(f: F) -> JoinHandle where F: FnOnce() -> T, @@ -1021,11 +1020,11 @@ impl Drop for PanicGuard { /// /// # Memory Ordering /// -/// Calls to `park` _synchronize-with_ calls to `unpark`, meaning that memory +/// Calls to `unpark` _synchronize-with_ calls to `park`, meaning that memory /// operations performed before a call to `unpark` are made visible to the thread that /// consumes the token and returns from `park`. Note that all `park` and `unpark` -/// operations for a given thread form a total order and `park` synchronizes-with -/// _all_ prior `unpark` operations. +/// operations for a given thread form a total order and _all_ prior `unpark` operations +/// synchronize-with `park`. /// /// In atomic ordering terms, `unpark` performs a `Release` operation and `park` /// performs the corresponding `Acquire` operation. Calls to `unpark` for the same @@ -1231,7 +1230,7 @@ impl ThreadId { } } - #[cfg(not(target_thread_local))] + #[cfg(any(not(target_thread_local), target_has_atomic = "64"))] fn from_u64(v: u64) -> Option { NonZero::new(v).map(ThreadId) } @@ -1257,29 +1256,14 @@ impl ThreadId { // This module ensures private fields are kept private, which is necessary to enforce the safety requirements. mod thread_name_string { - use core::str; - use crate::ffi::{CStr, CString}; + use crate::str; /// Like a `String` it's guaranteed UTF-8 and like a `CString` it's null terminated. pub(crate) struct ThreadNameString { inner: CString, } - impl ThreadNameString { - pub fn as_str(&self) -> &str { - // SAFETY: `self.inner` is only initialised via `String`, which upholds the validity invariant of `str`. - unsafe { str::from_utf8_unchecked(self.inner.to_bytes()) } - } - } - - impl core::ops::Deref for ThreadNameString { - type Target = CStr; - fn deref(&self) -> &CStr { - &self.inner - } - } - impl From for ThreadNameString { fn from(s: String) -> Self { Self { @@ -1287,82 +1271,124 @@ mod thread_name_string { } } } -} -pub(crate) use thread_name_string::ThreadNameString; - -static MAIN_THREAD_INFO: SyncUnsafeCell<(MaybeUninit, MaybeUninit)> = - SyncUnsafeCell::new((MaybeUninit::uninit(), MaybeUninit::uninit())); - -/// The internal representation of a `Thread` that is not the main thread. -struct OtherInner { - name: Option, - id: ThreadId, - parker: Parker, -} - -/// The internal representation of a `Thread` handle. -#[derive(Clone)] -enum Inner { - /// Represents the main thread. May only be constructed by Thread::new_main. - Main(&'static (ThreadId, Parker)), - /// Represents any other thread. - Other(Pin>), -} - -impl Inner { - fn id(&self) -> ThreadId { - match self { - Self::Main((thread_id, _)) => *thread_id, - Self::Other(other) => other.id, - } - } - fn cname(&self) -> Option<&CStr> { - match self { - Self::Main(_) => Some(c"main"), - Self::Other(other) => other.name.as_deref(), + impl ThreadNameString { + pub fn as_cstr(&self) -> &CStr { + &self.inner } - } - fn name(&self) -> Option<&str> { - match self { - Self::Main(_) => Some("main"), - Self::Other(other) => other.name.as_ref().map(ThreadNameString::as_str), + pub fn as_str(&self) -> &str { + // SAFETY: `ThreadNameString` is guaranteed to be UTF-8. + unsafe { str::from_utf8_unchecked(self.inner.to_bytes()) } } } +} - fn into_raw(self) -> *const () { - match self { - // Just return the pointer to `MAIN_THREAD_INFO`. - Self::Main(ptr) => crate::ptr::from_ref(ptr).cast(), - Self::Other(arc) => { - // Safety: We only expose an opaque pointer, which maintains the `Pin` invariant. - let inner = unsafe { Pin::into_inner_unchecked(arc) }; - Arc::into_raw(inner) as *const () +use thread_name_string::ThreadNameString; + +/// Store the ID of the main thread. +/// +/// The thread handle for the main thread is created lazily, and this might even +/// happen pre-main. Since not every platform has a way to identify the main +/// thread when that happens – macOS's `pthread_main_np` function being a notable +/// exception – we cannot assign it the right name right then. Instead, in our +/// runtime startup code, we remember the thread ID of the main thread (through +/// this modules `set` function) and use it to identify the main thread from then +/// on. This works reliably and has the additional advantage that we can report +/// the right thread name on main even after the thread handle has been destroyed. +/// Note however that this also means that the name reported in pre-main functions +/// will be incorrect, but that's just something we have to live with. +pub(crate) mod main_thread { + cfg_if::cfg_if! { + if #[cfg(target_has_atomic = "64")] { + use super::ThreadId; + use crate::sync::atomic::AtomicU64; + use crate::sync::atomic::Ordering::Relaxed; + + static MAIN: AtomicU64 = AtomicU64::new(0); + + pub(super) fn get() -> Option { + ThreadId::from_u64(MAIN.load(Relaxed)) } - } - } - /// # Safety - /// - /// See [`Thread::from_raw`]. - unsafe fn from_raw(ptr: *const ()) -> Self { - // If the pointer is to `MAIN_THREAD_INFO`, we know it is the `Main` variant. - if crate::ptr::eq(ptr.cast(), &MAIN_THREAD_INFO) { - Self::Main(unsafe { &*ptr.cast() }) + /// # Safety + /// May only be called once. + pub(crate) unsafe fn set(id: ThreadId) { + MAIN.store(id.as_u64().get(), Relaxed) + } } else { - // Safety: Upheld by caller - Self::Other(unsafe { Pin::new_unchecked(Arc::from_raw(ptr as *const OtherInner)) }) + use super::ThreadId; + use crate::mem::MaybeUninit; + use crate::sync::atomic::AtomicBool; + use crate::sync::atomic::Ordering::{Acquire, Release}; + + static INIT: AtomicBool = AtomicBool::new(false); + static mut MAIN: MaybeUninit = MaybeUninit::uninit(); + + pub(super) fn get() -> Option { + if INIT.load(Acquire) { + Some(unsafe { MAIN.assume_init() }) + } else { + None + } + } + + /// # Safety + /// May only be called once. + pub(crate) unsafe fn set(id: ThreadId) { + unsafe { MAIN = MaybeUninit::new(id) }; + INIT.store(true, Release); + } } } +} - fn parker(&self) -> Pin<&Parker> { - match self { - Self::Main((_, parker_ref)) => Pin::static_ref(parker_ref), - Self::Other(inner) => unsafe { - Pin::map_unchecked(inner.as_ref(), |inner| &inner.parker) - }, +/// Run a function with the current thread's name. +/// +/// Modulo thread local accesses, this function is safe to call from signal +/// handlers and in similar circumstances where allocations are not possible. +pub(crate) fn with_current_name(f: F) -> R +where + F: FnOnce(Option<&str>) -> R, +{ + try_with_current(|thread| { + if let Some(thread) = thread { + // If there is a current thread handle, try to use the name stored + // there. + if let Some(name) = &thread.inner.name { + return f(Some(name.as_str())); + } else if Some(thread.inner.id) == main_thread::get() { + // The main thread doesn't store its name in the handle, we must + // identify it through its ID. Since we already have the `Thread`, + // we can retrieve the ID from it instead of going through another + // thread local. + return f(Some("main")); + } + } else if let Some(main) = main_thread::get() + && let Some(id) = current::id::get() + && id == main + { + // The main thread doesn't always have a thread handle, we must + // identify it through its ID instead. The checks are ordered so + // that the current ID is only loaded if it is actually needed, + // since loading it from TLS might need multiple expensive accesses. + return f(Some("main")); } + + f(None) + }) +} + +/// The internal representation of a `Thread` handle +struct Inner { + name: Option, + id: ThreadId, + parker: Parker, +} + +impl Inner { + fn parker(self: Pin<&Self>) -> Pin<&Parker> { + unsafe { Pin::map_unchecked(self, |inner| &inner.parker) } } } @@ -1386,47 +1412,21 @@ impl Inner { /// docs of [`Builder`] and [`spawn`] for more details. /// /// [`thread::current`]: current::current -pub struct Thread(Inner); +pub struct Thread { + inner: Pin>, +} impl Thread { - /// Used only internally to construct a thread object without spawning. - pub(crate) fn new(id: ThreadId, name: String) -> Thread { - Self::new_inner(id, Some(ThreadNameString::from(name))) - } + pub(crate) fn new(id: ThreadId, name: Option) -> Thread { + let name = name.map(ThreadNameString::from); - pub(crate) fn new_unnamed(id: ThreadId) -> Thread { - Self::new_inner(id, None) - } - - /// Used in runtime to construct main thread - /// - /// # Safety - /// - /// This must only ever be called once, and must be called on the main thread. - pub(crate) unsafe fn new_main(thread_id: ThreadId) -> Thread { - // Safety: As this is only called once and on the main thread, nothing else is accessing MAIN_THREAD_INFO - // as the only other read occurs in `main_thread_info` *after* the main thread has been constructed, - // and this function is the only one that constructs the main thread. - // - // Pre-main thread spawning cannot hit this either, as the caller promises that this is only called on the main thread. - let main_thread_info = unsafe { &mut *MAIN_THREAD_INFO.get() }; - - unsafe { Parker::new_in_place((&raw mut main_thread_info.1).cast()) }; - main_thread_info.0.write(thread_id); - - // Store a `'static` ref to the initialised ThreadId and Parker, - // to avoid having to repeatedly prove initialisation. - Self(Inner::Main(unsafe { &*MAIN_THREAD_INFO.get().cast() })) - } - - fn new_inner(id: ThreadId, name: Option) -> Thread { // We have to use `unsafe` here to construct the `Parker` in-place, // which is required for the UNIX implementation. // // SAFETY: We pin the Arc immediately after creation, so its address never // changes. let inner = unsafe { - let mut arc = Arc::::new_uninit(); + let mut arc = Arc::::new_uninit(); let ptr = Arc::get_mut_unchecked(&mut arc).as_mut_ptr(); (&raw mut (*ptr).name).write(name); (&raw mut (*ptr).id).write(id); @@ -1434,7 +1434,7 @@ impl Thread { Pin::new_unchecked(arc.assume_init()) }; - Self(Inner::Other(inner)) + Thread { inner } } /// Like the public [`park`], but callable on any handle. This is used to @@ -1443,7 +1443,7 @@ impl Thread { /// # Safety /// May only be called from the thread to which this handle belongs. pub(crate) unsafe fn park(&self) { - unsafe { self.0.parker().park() } + unsafe { self.inner.as_ref().parker().park() } } /// Like the public [`park_timeout`], but callable on any handle. This is @@ -1452,7 +1452,7 @@ impl Thread { /// # Safety /// May only be called from the thread to which this handle belongs. pub(crate) unsafe fn park_timeout(&self, dur: Duration) { - unsafe { self.0.parker().park_timeout(dur) } + unsafe { self.inner.as_ref().parker().park_timeout(dur) } } /// Atomically makes the handle's token available if it is not already. @@ -1488,7 +1488,7 @@ impl Thread { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn unpark(&self) { - self.0.parker().unpark(); + self.inner.as_ref().parker().unpark(); } /// Gets the thread's unique identifier. @@ -1508,7 +1508,7 @@ impl Thread { #[stable(feature = "thread_id", since = "1.19.0")] #[must_use] pub fn id(&self) -> ThreadId { - self.0.id() + self.inner.id } /// Gets the thread's name. @@ -1551,11 +1551,13 @@ impl Thread { #[stable(feature = "rust1", since = "1.0.0")] #[must_use] pub fn name(&self) -> Option<&str> { - self.0.name() - } - - fn cname(&self) -> Option<&CStr> { - self.0.cname() + if let Some(name) = &self.inner.name { + Some(name.as_str()) + } else if main_thread::get() == Some(self.inner.id) { + Some("main") + } else { + None + } } /// Consumes the `Thread`, returning a raw pointer. @@ -1579,7 +1581,9 @@ impl Thread { /// ``` #[unstable(feature = "thread_raw", issue = "97523")] pub fn into_raw(self) -> *const () { - self.0.into_raw() + // Safety: We only expose an opaque pointer, which maintains the `Pin` invariant. + let inner = unsafe { Pin::into_inner_unchecked(self.inner) }; + Arc::into_raw(inner) as *const () } /// Constructs a `Thread` from a raw pointer. @@ -1601,7 +1605,17 @@ impl Thread { #[unstable(feature = "thread_raw", issue = "97523")] pub unsafe fn from_raw(ptr: *const ()) -> Thread { // Safety: Upheld by caller. - unsafe { Thread(Inner::from_raw(ptr)) } + unsafe { Thread { inner: Pin::new_unchecked(Arc::from_raw(ptr as *const Inner)) } } + } + + fn cname(&self) -> Option<&CStr> { + if let Some(name) = &self.inner.name { + Some(name.as_cstr()) + } else if main_thread::get() == Some(self.inner.id) { + Some(c"main") + } else { + None + } } } diff --git a/std/tests/env.rs b/std/tests/env.rs index 4e472b4ce9953..44fe84c989fb7 100644 --- a/std/tests/env.rs +++ b/std/tests/env.rs @@ -122,19 +122,19 @@ fn env_home_dir() { assert!(home_dir().is_some()); - set_var("HOME", "/home/MountainView"); + set_var("HOME", "/home/PaloAlto"); + assert_ne!(home_dir(), Some(PathBuf::from("/home/PaloAlto")), "HOME must not be used"); + + set_var("USERPROFILE", "/home/MountainView"); assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView"))); remove_var("HOME"); - set_var("USERPROFILE", "/home/MountainView"); assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView"))); - set_var("HOME", "/home/MountainView"); - set_var("USERPROFILE", "/home/PaloAlto"); - assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView"))); + set_var("USERPROFILE", ""); + assert_ne!(home_dir(), Some(PathBuf::from("")), "Empty USERPROFILE must be ignored"); - remove_var("HOME"); remove_var("USERPROFILE"); if let Some(oldhome) = oldhome { set_var("HOME", oldhome); } diff --git a/stdarch b/stdarch index e5e00aab0a8c8..684de0d6fef70 160000 --- a/stdarch +++ b/stdarch @@ -1 +1 @@ -Subproject commit e5e00aab0a8c8fa35fb7865e88fa82366f615c53 +Subproject commit 684de0d6fef708cae08214fef9643dd9ec7296e1 diff --git a/unwind/Cargo.toml b/unwind/Cargo.toml index 569a1b3299e5f..66e8d1a3ffe5f 100644 --- a/unwind/Cargo.toml +++ b/unwind/Cargo.toml @@ -22,7 +22,7 @@ cfg-if = "1.0" libc = { version = "0.2.140", features = ['rustc-dep-of-std'], default-features = false } [target.'cfg(target_os = "xous")'.dependencies] -unwinding = { version = "0.2.3", features = ['rustc-dep-of-std', 'unwinder', 'fde-custom'], default-features = false } +unwinding = { version = "0.2.5", features = ['rustc-dep-of-std', 'unwinder', 'fde-custom'], default-features = false } [features] @@ -37,7 +37,4 @@ system-llvm-libunwind = [] [lints.rust.unexpected_cfgs] level = "warn" -check-cfg = [ - # #[cfg(bootstrap)] rtems - 'cfg(target_os, values("rtems"))', -] +check-cfg = ['cfg(emscripten_wasm_eh)'] diff --git a/unwind/src/lib.rs b/unwind/src/lib.rs index 79baa5b0b83ec..e4ba2bc1ed874 100644 --- a/unwind/src/lib.rs +++ b/unwind/src/lib.rs @@ -4,10 +4,11 @@ #![feature(staged_api)] #![cfg_attr(not(target_env = "msvc"), feature(libc))] #![cfg_attr( - all(target_family = "wasm", not(target_os = "emscripten")), + all(target_family = "wasm", any(not(target_os = "emscripten"), emscripten_wasm_eh)), feature(simd_wasm64, wasm_exception_handling_intrinsics) )] #![allow(internal_features)] +#![cfg_attr(not(bootstrap), feature(cfg_emscripten_wasm_eh))] // Force libc to be included even if unused. This is required by many platforms. #[cfg(not(all(windows, target_env = "msvc")))] @@ -20,7 +21,6 @@ cfg_if::cfg_if! { target_os = "l4re", target_os = "none", target_os = "espidf", - target_os = "rtems", target_os = "nuttx", ))] { // These "unix" family members do not have unwinder. @@ -178,3 +178,8 @@ cfg_if::cfg_if! { #[cfg(target_os = "hurd")] #[link(name = "gcc_s")] extern "C" {} + +#[cfg(all(target_os = "windows", target_env = "gnu", target_abi = "llvm"))] +#[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))] +#[link(name = "unwind", cfg(not(target_feature = "crt-static")))] +extern "C" {} diff --git a/unwind/src/libunwind.rs b/unwind/src/libunwind.rs index 715f8b57876ae..1fa9e480166b7 100644 --- a/unwind/src/libunwind.rs +++ b/unwind/src/libunwind.rs @@ -102,12 +102,9 @@ pub type _Unwind_Exception_Cleanup_Fn = // rustc_codegen_ssa::src::back::symbol_export, rustc_middle::middle::exported_symbols // and RFC 2841 #[cfg_attr( - any( - all( - feature = "llvm-libunwind", - any(target_os = "fuchsia", target_os = "linux", target_os = "xous") - ), - all(target_os = "windows", target_env = "gnu", target_abi = "llvm") + all( + feature = "llvm-libunwind", + any(target_os = "fuchsia", target_os = "linux", target_os = "xous") ), link(name = "unwind", kind = "static", modifiers = "-bundle") )]