about summary refs log tree commit diff
path: root/src/libcore
AgeCommit message (Collapse)AuthorLines
2020-03-21Rollup merge of #70187 - matthiaskrgr:cl2ppy, r=Mark-SimulacrumMazdak Farrokhzad-1/+1
more clippy fixes * remove redundant returns (clippy::needless_return) * remove redundant import (clippy::single_component_path_imports) * remove redundant format!() call (clippy::useless_format) * don't use ok() before calling expect() (clippy::ok_expect)
2020-03-21Rollup merge of #70166 - CDirkx:range-inclusive-derives, r=cramertjMazdak Farrokhzad-22/+2
Derive PartialEq, Eq and Hash for RangeInclusive The manual implementation of `PartialEq`, `Eq` and `Hash` for `RangeInclusive` was functionally equivalent to a derived implementation. This change removes the manual implementation and adds the respective derives. A side effect of this change is that the derives also add implementations for `StructuralPartialEq` and `StructuralEq`, which enables `RangeInclusive` to be used in const generics, closing #70155. This change is enabled by #68835, which changed the field `is_empty: Option<bool>` to `exhausted: bool` removing the need for *semantic* equality instead of *structural* equality. ## PartialEq original [`PartialEq`](https://github.com/rust-lang/rust/blob/f4c675c476c18b1a11041193f2f59d695b126bc8/src/libcore/ops/range.rs#L353-L359) implementation: ```rust #[stable(feature = "inclusive_range", since = "1.26.0")] impl<Idx: PartialEq> PartialEq for RangeInclusive<Idx> { #[inline] fn eq(&self, other: &Self) -> bool { self.start == other.start && self.end == other.end && self.exhausted == other.exhausted } } ``` expanded derive implementation (using `cargo expand ops::range`): ```rust #[stable(feature = "inclusive_range", since = "1.26.0")] impl<Idx> crate::marker::StructuralPartialEq for RangeInclusive<Idx> {} #[automatically_derived] #[allow(unused_qualifications)] #[stable(feature = "inclusive_range", since = "1.26.0")] impl<Idx: crate::cmp::PartialEq> crate::cmp::PartialEq for RangeInclusive<Idx> { #[inline] fn eq(&self, other: &RangeInclusive<Idx>) -> bool { match *other { RangeInclusive { start: ref __self_1_0,end: ref __self_1_1, exhausted: ref __self_1_2 } => match *self { RangeInclusive { start: ref __self_0_0, end: ref __self_0_1, exhausted: ref __self_0_2 } => { (*__self_0_0) == (*__self_1_0) && (*__self_0_1) == (*__self_1_1) && (*__self_0_2) == (*__self_1_2) } }, } } #[inline] fn ne(&self, other: &RangeInclusive<Idx>) -> bool { match *other { RangeInclusive { start: ref __self_1_0, end: ref __self_1_1, exhausted: ref __self_1_2 } => match *self { RangeInclusive { start: ref __self_0_0, end: ref __self_0_1exhausted: ref __self_0_2 } => { (*__self_0_0) != (*__self_1_0) || (*__self_0_1) != (*__self_1_1) || (*__self_0_2) != (*__self_1_2) } }, } } } ``` These implementations both test for *structural* equality, with the same order of field comparisons, and the bound `Idx: PartialEq` is the same. ## Eq original [`Eq`](https://github.com/rust-lang/rust/blob/f4c675c476c18b1a11041193f2f59d695b126bc8/src/libcore/ops/range.rs#L361-L362) implementation: ```rust #[stable(feature = "inclusive_range", since = "1.26.0")] impl<Idx: Eq> Eq for RangeInclusive<Idx> {} ``` expanded derive implementation (using `cargo expand ops::range`): ```rust #[stable(feature = "inclusive_range", since = "1.26.0")] impl<Idx> crate::marker::StructuralEq for RangeInclusive<Idx> {} #[automatically_derived] #[allow(unused_qualifications)] #[stable(feature = "inclusive_range", since = "1.26.0")] impl<Idx: crate::cmp::Eq> crate::cmp::Eq for RangeInclusive<Idx> { #[inline] #[doc(hidden)] fn assert_receiver_is_total_eq(&self) -> () { { let _: crate::cmp::AssertParamIsEq<Idx>; let _: crate::cmp::AssertParamIsEq<Idx>; let _: crate::cmp::AssertParamIsEq<bool>; } } } ``` These implementations are equivalent since `Eq` is just a marker trait and the bound `Idx: Eq` is the same. ## Hash original [`Hash`](https://github.com/rust-lang/rust/blob/f4c675c476c18b1a11041193f2f59d695b126bc8/src/libcore/ops/range.rs#L364-L371) implementation: ```rust #[stable(feature = "inclusive_range", since = "1.26.0")] impl<Idx: Hash> Hash for RangeInclusive<Idx> { fn hash<H: Hasher>(&self, state: &mut H) { self.start.hash(state); self.end.hash(state); self.exhausted.hash(state); } } ``` expanded derive implementation (using `cargo expand ops::range`): ```rust #[automatically_derived] #[allow(unused_qualifications)] #[stable(feature = "inclusive_range", since = "1.26.0")] impl<Idx: crate::hash::Hash> crate::hash::Hash for RangeInclusive<Idx> { fn hash<__H: crate::hash::Hasher>(&self, state: &mut __H) -> () { match *self { RangeInclusive { start: ref __self_0_0, end: ref __self_0_1, exhausted: ref __self_0_2 } => { crate::hash::Hash::hash(&(*__self_0_0), state); crate::hash::Hash::hash(&(*__self_0_1), state); crate::hash::Hash::hash(&(*__self_0_2), state) } } } } ``` These implementations are functionally equivalent, with the same order of field hashing, and the bound `Idx: Hash` is the same.
2020-03-21Rollup merge of #70038 - DutchGhost:const-forget-tests, r=RalfJungMazdak Farrokhzad-18/+0
Remove the call that makes miri fail Fixes the concern raised in https://github.com/rust-lang/rust/pull/69645/files#r392884274 cc @RalfJung
2020-03-21Rollup merge of #69997 - WaffleLapkin:option_zip, r=LukasKalbertodtMazdak Farrokhzad-0/+58
add `Option::{zip,zip_with}` methods under "option_zip" gate This PR introduces 2 methods - `Option::zip` and `Option::zip_with` with respective signatures: - zip: `(Option<T>, Option<U>) -> Option<(T, U)>` - zip_with: `(Option<T>, Option<U>, (T, U) -> R) -> Option<R>` Both are under the feature gate "option_zip". I'm not sure about the name "zip", maybe we can find a better name for this. (I would prefer `union` for example, but this is a keyword :( ) -------------------------------------------------------------------------------- Recently in a russian rust begginers telegram chat a newbie asked (translated): > Are there any methods for these conversions: > > 1. `(Option<A>, Option<B>) -> Option<(A, B)>` > 2. `Vec<Option<T>> -> Option<Vec<T>>` > > ? While second (2.) is clearly `vec.into_iter().collect::<Option<Vec<_>>()`, the first one isn't that clear. I couldn't find anything similar in the `core` and I've come to this solution: ```rust let tuple: (Option<A>, Option<B>) = ...; let res: Option<(A, B)> = tuple.0.and_then(|a| tuple.1.map(|b| (a, b))); ``` However this solution isn't "nice" (same for just `match`/`if let`), so I thought that this functionality should be in `core`.
2020-03-21Rollup merge of #69033 - jonas-schievink:resume-with-context, r=tmandryMazdak Farrokhzad-0/+78
Use generator resume arguments in the async/await lowering This removes the TLS requirement from async/await and enables it in `#![no_std]` crates. Closes https://github.com/rust-lang/rust/issues/56974 I'm not confident the HIR lowering is completely correct, there seem to be quite a few undocumented invariants in there. The `async-std` and tokio test suites are passing with these changes though.
2020-03-20remove redundant returns (clippy::needless_return)Matthias Krüger-1/+1
2020-03-20Auto merge of #69509 - RalfJung:debug-assert-write, r=eddybbors-3/+1
debug-assert ptr sanity in ptr::write This is a re-submission of the parts that we removed from https://github.com/rust-lang/rust/pull/69208 due to ["interesting" test failures](https://github.com/rust-lang/rust/pull/69208#issuecomment-591310437). Fixes https://github.com/rust-lang/rust/issues/53871 r? @Mark-Simulacrum @eddyb
2020-03-19Removed unused `Hasher` import.CDirkx-1/+1
2020-03-19Derive PartialEq, Eq and Hash for RangeInclusiveCDirkx-21/+1
The manual implementation of PartialEq, Eq and Hash for RangeInclusive was functionally equivalent to a derived implementation. This change removes the manual implementation and adds the respective derives. A side effect of this change is that the derives also add implementations for StructuralPartialEq and StructuralEq, which enables RangeInclusive to be used in const generics.
2020-03-19make "other" in docs of `Option::{zip,zip_with}` monofontWaffle-2/+2
2020-03-19Don't hard-code the vector length in the examples.Hrvoje Nikšić-4/+3
Co-Authored-By: lzutao <taolzu@gmail.com>
2020-03-19Minor re-wordings and typo fixes.Hrvoje Nikšić-8/+8
Co-Authored-By: Ralf Jung <post@ralfj.de>
2020-03-19Restore (and reword) the warning against passing invalid values to mem::forget.Hrvoje Niksic-17/+35
As pointed out by Ralf Jung, dangling references and boxes are undefined behavior as per https://doc.rust-lang.org/reference/behavior-considered-undefined.html and the Miri checker.
2020-03-19Clarify the relationship between `forget()` and `ManuallyDrop`.Hrvoje Niksic-11/+27
As discussed on reddit, this commit addresses two issues with the documentation of `mem::forget()`: * The documentation of `mem::forget()` can confuse the reader because of the discrepancy between usage examples that show correct usage and the accompanying text which speaks of the possibility of double-free. The text that says "if the panic occurs before `mem::forget` was called" refers to a variant of the second example that was never shown, modified to use `mem::forget` instead of `ManuallyDrop`. Ideally the documentation should show both variants, so it's clear what it's talking about. Also, the double free could be fixed just by placing `mem::forget(v)` before the construction of `s`. Since the lifetimes of `s` and `v` wouldn't overlap, there would be no point where panic could cause a double free. This could be mentioned, and contrasted against the more robust fix of using `ManuallyDrop`. * This sentence seems unjustified: "For some types, operations such as passing ownership (to a funcion like `mem::forget`) requires them to actually be fully owned right now [...]". Unlike C++, Rust has no move constructors, its moves are (possibly elided) bitwise copies. Even if you pass an invalid object to `mem::forget`, no harm should come to pass because `mem::forget` consumes the object and exists solely to prevent drop, so there no one left to observe the invalid state state.
2020-03-19Rollup merge of #70088 - tmiasko:atomic-copy, r=eddybMazdak Farrokhzad-15/+15
Use copy bound in atomic operations to generate simpler MIR
2020-03-19Rollup merge of #69929 - cuviper:unicode-13.0.0, r=Mark-SimulacrumMazdak Farrokhzad-445/+462
Regenerate tables for Unicode 13.0.0
2020-03-18Move the const-forget test into ui testsDutchGhost-18/+0
2020-03-18fixes to `Option::{zip,zip_with}`Waffle-11/+9
- remove `#[inline]` attributes (see https://github.com/rust-lang/rust/pull/69997#discussion_r393942617) - fill tracking issue in `#[unstable]` attributes - slightly improve the docs
2020-03-18add `Option::{zip,zip_with}` methods under "option_zip" gateWaffle-0/+60
This commit introduces 2 methods - `Option::zip` and `Option::zip_with` with respective signatures: - zip: `(Option<T>, Option<U>) -> Option<(T, U)>` - zip_with: `(Option<T>, Option<U>, (T, U) -> R) -> Option<R>` Both are under the feature gate "option_zip". I'm not sure about the name "zip", maybe we can find a better name for this. (I would prefer `union` for example, but this is a keyword :( ) -------------------------------------------------------------------------------- Recently in a russian rust begginers telegram chat a newbie asked (translated): > Are there any methods for these conversions: > > 1. `(Option<A>, Option<B>) -> Option<(A, B)>` > 2. `Vec<Option<T>> -> Option<Vec<T>>` > > ? While second (2.) is clearly `vec.into_iter().collect::<Option<Vec<_>>()`, the first one isn't that clear. I couldn't find anything similar in the `core` and I've come to this solution: ```rust let tuple: (Option<A>, Option<B>) = ...; let res: Option<(A, B)> = tuple.0.and_then(|a| tuple.1.map(|b| (a, b))); ``` However this solution isn't "nice" (same for just `match`/`if let`), so I thought that this functionality should be in `core`.
2020-03-18Auto merge of #68915 - timvermeulen:non_fused_iter, r=Amanieubors-9/+90
Fix bugs in Peekable and Flatten when using non-fused iterators I fixed a couple of bugs with regard to the `Peekable` and `Flatten`/`FlatMap` iterators when the underlying iterator isn't fused. For testing, I also added a `NonFused` iterator wrapper that panics when `next` or `next_back` is called on an iterator that has returned `None` before, which will hopefully make it easier to spot these mistakes in the future. ### Peekable `Peekable::next_back` was implemented as ```rust self.iter.next_back().or_else(|| self.peeked.take().and_then(|x| x)) ``` which is incorrect because when the `peeked` field is `Some(None)`, then `None` has already been returned from the inner iterator and what it returns from `next_back` can no longer be relied upon. `test_peekable_non_fused` tests this. ### Flatten When a `FlattenCompat` instance only has a `backiter` remaining (i.e. `self.frontiter` is `None` and `self.iter` is empty), then `next` will call `self.iter.next()` every time, so the `iter` field needs to be fused. I fixed it by giving it the type `Fuse<I>` instead of `I`, I think this is the only way to fix it. `test_flatten_non_fused_outer` tests this. Furthermore, previously `FlattenCompat::next` did not set `self.frontiter` to `None` after it returned `None`, which is incorrect when the inner iterator type isn't fused. I just delegated it to `try_fold` because that already handles it correctly. `test_flatten_non_fused_inner` tests this. r? @scottmcm
2020-03-18Use copy bound in atomic operations to generate simpler MIRTomasz Miąsko-15/+15
2020-03-17Add issue referenceJonas Schievink-1/+1
2020-03-17Clarify commentJonas Schievink-1/+1
2020-03-17Make `ResumeTy` contents privateJonas Schievink-1/+1
2020-03-17Remove useless derives on `GenFuture`Jonas Schievink-1/+0
Not sure why these were there, I guess because this type used to kind of be part of public API?
2020-03-17FormatJonas Schievink-1/+1
2020-03-17Add futures scaffolding to libcoreJonas Schievink-0/+79
2020-03-17Rollup merge of #69922 - RalfJung:less-intrinsic, r=oli-obkMazdak Farrokhzad-43/+5
implement zeroed and uninitialized with MaybeUninit This is the second attempt of doing such a change (first PR: https://github.com/rust-lang/rust/pull/62150). The last change [got reverted](https://github.com/rust-lang/rust/pull/63343) because it [caused](https://github.com/rust-lang/rust/issues/62825) some [issues](https://github.com/rust-lang/rust/issues/52898#issuecomment-512182438) in [code that incorrectly used these functions](https://github.com/erlepereira/x11-rs/issues/99). Since then, the [problematic code has been fixed](https://github.com/erlepereira/x11-rs/pull/101), and rustc [gained a lint](https://github.com/rust-lang/rust/pull/63346) that is able to detect many misuses of these functions statically and a [dynamic check that panics](https://github.com/rust-lang/rust/pull/66059) instead of causing UB for some incorrect uses. Fixes https://github.com/rust-lang/rust/issues/62825
2020-03-17Rollup merge of #70029 - jonas-schievink:bootstrap, r=CentrilMazdak Farrokhzad-31/+4
Bump the bootstrap compiler
2020-03-17Rollup merge of #69870 - petrochenkov:cfgacc, r=matthewjasperMazdak Farrokhzad-0/+21
expand: Implement something similar to `#[cfg(accessible(path))]` cc https://github.com/rust-lang/rust/issues/64797 The feature is implemented as a `#[cfg_accessible(path)]` attribute macro rather than as `#[cfg(accessible(path))]` because it needs to wait until `path` becomes resolvable, and `cfg` cannot wait, but macros can wait. Later we can think about desugaring or not desugaring `#[cfg(accessible(path))]` into `#[cfg_accessible(path)]`. This implementation is also incomplete in the sense that it never returns "false" from `cfg_accessible(path)`, it requires some tweaks to resolve, which is not quite ready to answer queries like this during early resolution. However, the most important part of this PR is not `cfg_accessible` itself, but expansion infrastructure for retrying expansions. Before this PR we could say "we cannot resolve this macro path, let's try it later", with this PR we can say "we cannot expand this macro, let's try it later" as well. This is a pre-requisite for - turning `#[derive(...)]` into a regular attribute macro, - properly supporting eager expansion for macros that cannot yet be resolved like ``` fn main() { println!(not_available_yet!()); } macro_rules! make_available { () => { #[macro_export] macro_rules! not_available_yet { () => { "Hello world!" } }} } make_available!(); ```
2020-03-17Add testsTim Vermeulen-0/+72
2020-03-17Fix FlattenCompat::{next, next_back}Tim Vermeulen-4/+6
2020-03-16Auto merge of #68970 - matthewjasper:min-spec, r=nikomatsakisbors-0/+1
Implement a feature for a sound specialization subset This implements a new feature (`min_specialization`) that restricts specialization to a subset that is reasonable for the standard library to use. The plan is to then: * Update `libcore` and `liballoc` to compile with `min_specialization`. * Add a lint to forbid use of `feature(specialization)` (and other unsound, type system extending features) in the standard library. * Fix the soundness issues around `specialization`. * Remove `min_specialization` The rest of this is an overview from a comment in this PR ## Basic approach To enforce this requirement on specializations we take the following approach: 1. Match up the substs for `impl2` so that the implemented trait and self-type match those for `impl1`. 2. Check for any direct use of `'static` in the substs of `impl2`. 3. Check that all of the generic parameters of `impl1` occur at most once in the *unconstrained* substs for `impl2`. A parameter is constrained if its value is completely determined by an associated type projection predicate. 4. Check that all predicates on `impl1` also exist on `impl2` (after matching substs). ## Example Suppose we have the following always applicable impl: ```rust impl<T> SpecExtend<T> for std::vec::IntoIter<T> { /* specialized impl */ } impl<T, I: Iterator<Item=T>> SpecExtend<T> for I { /* default impl */ } ``` We get that the subst for `impl2` are `[T, std::vec::IntoIter<T>]`. `T` is constrained to be `<I as Iterator>::Item`, so we check only `std::vec::IntoIter<T>` for repeated parameters, which it doesn't have. The predicates of `impl1` are only `T: Sized`, which is also a predicate of impl2`. So this specialization is sound. ## Extensions Unfortunately not all specializations in the standard library are allowed by this. So there are two extensions to these rules that allow specializing on some traits. ### rustc_specialization_trait If a trait is always applicable, then it's sound to specialize on it. We check trait is always applicable in the same way as impls, except that step 4 is now "all predicates on `impl1` are always applicable". We require that `specialization` or `min_specialization` is enabled to implement these traits. ### rustc_specialization_marker There are also some specialization on traits with no methods, including the `FusedIterator` trait which is advertised as allowing optimizations. We allow marking marker traits with an unstable attribute that means we ignore them in point 3 of the checks above. This is unsound but we allow it in the short term because it can't cause use after frees with purely safe code in the same way as specializing on traits methods can. r? @nikomatsakis cc #31844 #67194
2020-03-16make mem::{zeroed,uninitialized} inline(always)Ralf Jung-2/+2
2020-03-16rather than removing const_forget_box, stick an attribute on it and explain ↵DutchGhost-0/+12
it cant be called in ctfe yet
2020-03-16The const_forget_box was unused, and doesns't add anything to test by itself.DutchGhost-8/+0
2020-03-16Remove the call that makes miri failDutchGhost-4/+0
2020-03-15Bump the bootstrap compilerJonas Schievink-31/+4
2020-03-15Rollup merge of #69528 - HeroicKatora:finalize-ref-cell, r=dtolnayMazdak Farrokhzad-5/+36
Add undo_leak to reset RefCell borrow state This method is complementary for the feature cell_leak added in an earlier PR. It allows *safely* reverting the effects of leaking a borrow guard by statically proving that such a guard could not longer exist. This was not added to the existing `get_mut` out of concern of impacting the complexity of the otherwise pure pointer cast and because the name `get_mut` poorly communicates the intent of resetting remaining borrows. This is a follow-up to #68712 and uses the same tracking issue, #69099, as these methods deal with the same mechanism and the idea came up [in a review comment](https://github.com/rust-lang/rust/pull/68712#discussion_r384670041). @dtolnay who reviewed the prior PR. cc @RalfJung
2020-03-15Add attributes to allow specializing on traitsMatthew Jasper-0/+1
2020-03-15Rollup merge of #69471 - nnethercote:rm-sip-Hasher-short_write, r=dtolnayDylan DPC-46/+7
Remove `sip::Hasher::short_write`. `sip::Hasher::short_write` is currently unused. It is called by `sip::Hasher::write_{u8,usize}`, but those methods are also unused, because `DefaultHasher`, `SipHasher` and `SipHasher13` don't implement any of the `write_xyz` methods, so all their write operations end up calling `sip::Hasher::write`. (I confirmed this by inserting a `panic!` in `sip::Hasher::short_write` and running the tests -- they all passed.) The alternative would be to add all the missing `write_xyz` methods. This does give some significant speed-ups, but it hurts compile times a little in some cases. See #69152 for details. This commit does the conservative thing and doesn't change existing behaviour. r? @rust-lang/libs
2020-03-14debug-assert ptr sanity in ptr::writeRalf Jung-3/+1
2020-03-14adjust Miri interaction with panic runtimeRalf Jung-3/+5
2020-03-13Auto merge of #67502 - Mark-Simulacrum:opt-catch, r=Mark-Simulacrumbors-6/+8
Optimize catch_unwind to match C++ try/catch This refactors the implementation of catching unwinds to allow LLVM to inline the "try" closure directly into the happy path, avoiding indirection. This means that the catch_unwind implementation is (after this PR) zero-cost unless a panic is thrown. https://rust.godbolt.org/z/cZcUSB is an example of the current codegen in a simple case. Notably, the codegen is *exactly the same* if `-Cpanic=abort` is passed, which is clearly not great. This PR, on the other hand, generates the following assembly: ```asm # -Cpanic=unwind: push rbx mov ebx,0x2a call QWORD PTR [rip+0x1c53c] # <happy> mov eax,ebx pop rbx ret mov rdi,rax call QWORD PTR [rip+0x1c537] # cleanup function call call QWORD PTR [rip+0x1c539] # <unfortunate> mov ebx,0xd mov eax,ebx pop rbx ret # -Cpanic=abort: push rax call QWORD PTR [rip+0x20a1] # <happy> mov eax,0x2a pop rcx ret ``` Fixes #64224, and resolves #64222.
2020-03-14Rollup merge of #69973 - tspiteri:const-int-conversion-since, r=dtolnayYuki Okushi-12/+12
Update stable-since version for const_int_conversion Since #69373 was not merged in time for 1.43.0 beta, update to `since = "1.44.0"`.
2020-03-14Rollup merge of #69954 - RalfJung:panic_if-assert, r=Centril,eddybYuki Okushi-4/+22
rename panic_if_ intrinsics to assert_ [Suggested by @eddyb](https://github.com/rust-lang/miri/issues/1222#issuecomment-598087523)
2020-03-14Rollup merge of #69802 - matthiaskrgr:cl1ppy, r=Dylan-DPCYuki Okushi-8/+5
fix more clippy findings * reduce references on match patterns (clippy::match_ref_pats) * Use writeln!(fmt, "word") instead of write!(fmt, "word\n") (clippy::write_with_newline) * libtest: remove redundant argument to writeln!() (clippy::writeln_empty_string) * remove unneeded mutable references (cippy::unnecessary_mut_passed) * libtest: declare variables as floats instead of casting them (clippy::unnecessary_cast) * rustdoc: remove redundant static lifetimes (clippy::redundant_static_lifetimes) * call .as_deref() instead of .as_ref().map(Deref::deref) (clippy::option_as_ref_deref) * iterate over a maps values directly. (clippy::for_kv_map) * rustdoc: simplify boolean condition (clippy::nonminimal_bool) * Use ?-operator in more places (clippy::question_mark, had some false negatives fixed recently) * rustdoc: Use .any(p) instead of find(p).is_some(). (clippy::search_is_some) * rustdoc: don't call into_iter() on iterator. (clippy::identity_conversion)
2020-03-13update stable-since version for const_int_conversionTrevor Spiteri-12/+12
2020-03-12rename panic_if_ intrinsics to assert_Ralf Jung-4/+22
2020-03-12Rollup merge of #69011 - foeb:document-unsafe-core-fmt, r=Mark-SimulacrumMazdak Farrokhzad-6/+45
Document unsafe blocks in core::fmt r? @RalfJung CC: @rust-lang/wg-unsafe-code-guidelines #66219 Sorry for the hiatus, but here's a few more files with the unsafe blocks documented! I think working on it smaller chunks like this will be easier for everyone.