Awesome
What is this?
Once upon a time, Jon Gjengset did a Rust trivia on Twitter. This is the thread, unrolled and cleaned up (with permission):
:nerd_face: You can also check out the keywords thread.
Rust Trivia
Did you know that in its default configuration, TcpStream uses Nagle's Algorithm to schedule packet sends (https://en.wikipedia.org/wiki/Nagle%27s_algorithm), which can introduce unfortunate latency spikes. If you're particularly latency sensitive, consider calling TcpStream::set_nodelay(true)
Did you know that the
Formatter
argument toDebug::fmt
makes it really easy to customize debug representations for structs, enums, lists, and sets? See thedebug_*
methods on it and
Did you know that std::fmt::Formatter is super easy to use if you want more control over debugging for a custom type. For example, to emit a "list-like" type, just Formatter::debug_list().entries(self.0.iter()).finish()
Did you know that Option<T> implements IntoIterator yielding 0/1 elements, and you can then call Iterator::flatten to make that be 0/n elements if T: IntoIterator?
std::sync::mpsc::channel::Sender
Did you know that std::sync::mpsc has had a known bug since 2017 (https://github.com/rust-lang/rust/issues/39364), and that the implementation may actually be replaced entirely with the crossbeam channel implementation? https://github.com/rust-lang/rust/pull/93563
type EmptyTupleList = Vec<()>:
Did you know that since () is a zero-sized type, and the vector never actually has to store any data, the capacity of Vec<()> is usize::MAX!
Did you know that Box<T> is a #[fundamental] type, which means that it's exempt from the normal rules that don't allow you to implement foreign traits for foreign types (assuming T is a local type)?
Did you know that T doesn't imply ownership? When we say a type is generic over T, that T can just as easily be a reference to something on the stack, and the type system will still be happy. Even T: 'static doesn't imply owned — consider &'static str for example.
Did you know that even though we got u128 a long time ago now, we still don't have repr(128)? https://github.com/rust-lang/rust/issues/56071
Did you know that there are per-platform extension traits for OsString that bake in the assumptions you can safely make on that platform? Such as strings being [u8] on Unix (https://doc.rust-lang.org/std/os/unix/ffi/trait.OsStringExt.html) and UTF-16 on Windows (https://doc.rust-lang.org/std/os/windows/ffi/trait.OsStringExt.html).
Did you know that one of the super neat features of NonNull is that it enables the same niche optimization that regular references and the NonZero* types get where Option<NonNull<T>> is the same size as *mut T?
Did you know that there used to be a special IntoCow trait, but it was deprecated before 1.0 was released! https://github.com/rust-lang/rust/issues/27735
Did you know that std has three different ways to spawn a child process on Linux (posix_spawn, clone3/exec, fork/exec) depending on what capabilities your kernel version has? https://github.com/rust-lang/rust/blob/master/library/std/src/sys/unix/process/process_unix.rs
Did you know that the name Pin (and the name Unpin) where both heavily debated? Pin was almost called Pinned, for example. The discussion in https://github.com/rust-lang/rust/issues/55766#issuecomment-438789462 is an interesting read now after the fact.
I'm going to pretend you said CStr, and say: did you know that CStr::default creates a CStr that points to a const string "0" stored in the binary text segment, which means all default CStrs point to the same (non-null) string!
Did you know that in Rust 1.62 we'll get a deterministic ordering function for floating point numbers? https://github.com/rust-lang/rust/pull/95431
Did you know that Vec::swap_remove is way faster than Vec::remove if you can tolerate changes to ordering?
But since it's you, here's another: did you know that the smallest non-zero capacity for a Vec<T> depends on the size of T? https://github.com/rust-lang/rust/blob/9a74608543d499bcc7dd505e195e8bfab9447315/library/alloc/src/raw_vec.rs#L106-L110
Did you know that you can use for<'a> to say that a bound has to hold for any lifetime 'a, not just a specific lifetime you happen to have available at the time. For example, <T> for<'a>: &'a T: Read says that any shared reference to a T must implement Read.
Did you know that until Rust 1.35, you couldn't call a Box<dyn FnOnce> and needed a special type (FnBox) for it! This was because it requires "unsized rvalues" to implement, which are still unstable today. https://github.com/rust-lang/rust/issues/28796 + https://github.com/rust-lang/rust/issues/48055
Did you know that the Rc type was among the arguments for why std::mem::forget shouldn't be marked as
unsafe
? https://github.com/rust-lang/rust/issues/24456
Did you know that the ThreadId that's available for each Thread is entirely a std construct? Creating a ThreadId simply increments a global static counter under a lock.
Did you know that Arc has a make_mut method that effectively gives you copy-on-write? Given a &mut Arc<T>, it will either give you &mut T if there are no other Arcs, or it will clone T, make the Arc<T> point to that new T, and then give you a &mut to it!
Did you know that std::convert::Infallible is the "original" !, and that the plan is to one day replace Infallible with a type alias for !?
Specifically, did you know that the name of a function is not an fn? It's a "FnDef", which can then be coerced to a "FnPtr": https://github.com/rust-lang/rust/issues/86654#issuecomment-869173835
Did you know that it's actually kind of tricky to define PhantomData yourself: https://github.com/dtolnay/ghost
std::os::unix::net::UnixStream
Did you know that (on nightly) you can pass UNIX file descriptors over UnixStreams too, and thereby give another process access to a file it may not otherwise be able to open? https://doc.rust-lang.org/std/os/unix/net/struct.SocketAncillary.html#method.add_fds
std::sync::Condvar
(and Mutex
)
Did you know that Mara is doing some awesome work on making Condvar (and Mutex and RwLock) much better on a wide array on platforms? https://github.com/rust-lang/rust/issues/93740
Did you know that bool isn't just "stored as a byte", the compiler straight up declares its representation as the same as that of u8? https://github.com/rust-lang/rust/blob/master/compiler/rustc_middle/src/ty/layout.rs#L676-L682
Did you know that Any is really non-magical? It just has a blanket implementation for all T that returns TypeId::of::<T>(), and to downcast it simply compares the return value of that trait method to see if it's safe to cast to downcast to a type! TypeId is magic though.
Did you know that
fn foo(self)
is syntactic sugar forfn foo(self: Self)
, and that one day you'll be able to use other types forself
that involveSelf
, likefn foo(self: Arc<Self>)
. https://github.com/rust-lang/rust/issues/44874
Did you know that there are implementations of Read, Write, and Seek for &File as well, so multiple threads can share a single File and call those concurrently. Whether they should is a different question of course.
Did you know that u32 now has associated constants for MIN and MAX, so you no longer need to use std::u32::MIN and can use u32::MIN directly instead.
Did you know that BTreeMap is one of the few collections that still doesn't have a drain method? https://github.com/rust-lang/rust/issues/81074
struct InvariantLifetime<'id>(PhantomData<*mut &'id ()>);
Did you know that PhantomData<T> has variance like T, and *mut T is invariant over T, and so by placing a lifetime inside T you make the outer type invariant over that lifetime?
Did you know that these days you can just use
async move { x }
instead offuture::ready(x)
. The main reason to still usefuture::ready(x)
is that you can name the future it returns, which is harder withasync
(withouttype_alias_impl_trait
that is).
Did you know that
usize
isn't really "the size of a pointer". Instead, it's more like "the size of a pointer address difference", and the two can be fairly different! https://github.com/rust-lang/rust/issues/95228
Did you know that RefCell allows you to replace a value in-place directly (like std::mem::replace)? https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.replace
Did you know that since PanicInfo is in
core
, its Display implementation cannot access the panic data if it's a String (since it can't name that type), so trying to print the PanicInfo after a std::panic::panic_any(format!("x y z")) won't print "x y z"? https://github.com/rust-lang/rust/blob/352e621368c31d7b4a6362e081586cdb931ba020/library/core/src/panic/panic_info.rs#L159-L162
Did you know that there used to also be a trait accompanying Wrapping, WrappingOps, that was removed last minute before 1.0? https://github.com/rust-lang/rust/pull/23549
Did you know that, at least for the time being, *const T and *mut T are more or less equivalent? https://github.com/rust-lang/unsafe-code-guidelines/issues/257
Did you know that Waker is secretly just a
dyn std::task::Wake + Clone
done in a way that doesn't require a wide pointer or support for multi-trait dynamic dispatch? See https://doc.rust-lang.org/std/task/struct.RawWakerVTable.html
Did you know that impl Trait in argument position and impl Trait in return position represent completely different type constructs, even though they "feel" related? https://doc.rust-lang.org/nightly/reference/types/impl-trait.html
Did you know that ControlFlow is really a stepping stone towards making ? work for other types than Option and Result? The full design has gone through a lot of iterations, but the latest and greatest is RFC3058: https://github.com/rust-lang/rust/issues/84277
Did you know that Rust originally (pre-1.0) had both Result and an Either type? They decided to remove Either way back in 2013: https://github.com/rust-lang/rust/issues/9157
Did you know that because Cow<'a, T> is covariant in 'a, you can always assign Cow::Borrowed("some string") to one no matter what it originally held?
That's cheating, but I'll bite.
Did you know that () implements FromIterator, so you can .collect::<Result<(), E>> to just see if anything in an iterator erred?
Did you know that struct S implicitly declares a constant called S, which is why you can make one using just S?
Did you know that the whole c_void type is a collection of hacks to try to work around the lack for extern types? https://github.com/rust-lang/rust/issues/43467
Did you know that because Rust compiles through LLVM, we're sort of constrained to the primitive types LLVM supports, and LLVM itself only goes up to 128? https://llvm.org/doxygen/classllvm_1_1Type.html#pub-static-methods
Did you know that as of Rust 1.60, you can now use u8::escape_ascii to get an iterator of the bytes needed to escape that byte character in most contexts: https://doc.rust-lang.org/std/ascii/fn.escape_default.html
#[feature(raw_ref_op)] &raw const T
Definitely cheating :p But did you know that originally the intention was to have &const raw variable be just a MIR construct and let &variable as *const _ be automatically changed to &const raw? https://github.com/RalfJung/rfcs/blob/fd4b4cd769300cfde5d54865d227990b71b762d1/text/0000-raw-reference-operator.md
Did you know that Hash is responsible for not just one, but two of the issues on the "rust 2 breakage wishlist"? https://github.com/rust-lang/rust/issues/29263 https://github.com/rust-lang/rust/issues/65744
Did you know that whether or not let _ = x should move x is actually fairly subtle? https://github.com/rust-lang/rust/issues/10488
Did you know that MaybeUninit arose because the previous mechanism, std::mem::uninitialized, produced immediate undefined behavior when invoked with most types (like uninitialized::<bool>()).
Did you know that with Rust 1.59.0 you can now give C a default value? https://blog.rust-lang.org/2022/02/24/Rust-1.59.0.html#const-generics-defaults-and-interleaving
Did you know that actual deallocation logic for Arc<T> is implemented in Weak<T>, and is invoked by considering all copies of a particular Arc<T> to collectively hold a single Weak<T> between them? https://github.com/rust-lang/rust/blob/7e9b92cb43a489b34e2bcb8d21f36198e02eedbc/library/alloc/src/sync.rs#L1108-L1109
Did you know that while most trait implementations for arrays now use const generics to impl for any length N, we can't yet do the same for Default: https://github.com/rust-lang/rust/blob/e40d5e83dc133d093c22c7ff016b10daa4f40dcf/library/core/src/array/mod.rs#L371-L394
Did you know that the Rust devs are working on a "raw" entry API for HashMap that allows you to (unsafely) avoid re-hashing a key you've already hashed? https://github.com/rust-lang/rust/issues/56167
Did you know that while &mut T is defined as meaning "mutable reference" in the Rust reference, you're often better off thinking of it as "mutually exclusive reference". Quoth David Tolnay: https://docs.rs/dtolnay/latest/dtolnay/macro._02__reference_types.html
Did you know that there's been a lot of debate around whether or not the Range types should be Copy? https://github.com/rust-lang/rust/pull/21846
Did you know that you'll often want compare_exchange_weak over compare_exchange to get more efficient code on ARM cores: https://devblogs.microsoft.com/oldnewthing/20180329-00/?p=98375
Did you know that fasterthanlime's most recent article does a great job at explaining
{integer}
? https://fasterthanli.me/articles/the-curse-of-strong-typing#different-kinds-of-numbers
Did you know that until Rust 1.35.0, Box<T> where T: Fn did not impl Fn, so you couldn't (easily) call boxed closures! https://github.com/rust-lang/rust/pull/55431
Did you know that ((), ()) and () have the same hash? https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=894b78e8ee2721440aa8dea5e35f9dc3
Did you know that &[u8] implements Read and Write? So for anything that takes impl Read, you can provide &mut slice instead! Comes in handy for testing. Note that the slice itself is shortened for each read, hence &mut &[u8].
Did you know that
*
is (mostly) just syntax sugar for the std::ops::Mul trait?
Did you know that UnsafeCell is one of those types that the compiler needs "special magic" for because it has to instruct LLVM to not assume Rust's normal aliasing rules hold once code traverses the boundary of any UnsafeCell?