rust-lang/rust
std
library/std/ is the full standard library — what extern crate std (implicit in every program) gives you. It's the layer that knows about the host operating system.
Purpose
std adds, on top of core and alloc:
- Filesystem access (
std::fs) - Process spawning, env vars, command-line arguments (
std::process,std::env) - Networking (
std::net) - Threads (
std::thread) - Sync primitives — mutexes, rwlocks, condvars, channels, OnceLock (
std::sync,std::sync::mpsc) - Time (
std::time, monotonic and wall clocks) - I/O (
std::io—Read,Write,BufRead,BufWriter, …) - Hash maps (
std::collections::HashMap,HashSet) - Panicking + unwinding (
std::panic, hooks, catch_unwind)
Directory layout
library/std/
├── Cargo.toml
├── src/
│ ├── lib.rs # Crate root; re-exports core/alloc, exports own modules
│ ├── prelude/ # The 2015/2018/2021/2024 preludes
│ ├── alloc.rs # std::alloc::System (the default allocator)
│ ├── env.rs # env::var, env::args, env::current_dir
│ ├── fs.rs # File, Metadata, OpenOptions
│ ├── io/ # Read, Write, Stdin/Stdout, BufRead, …
│ ├── net/ # TcpStream, UdpSocket, IpAddr
│ ├── process/ # Command, Child, Stdio
│ ├── thread/ # spawn, JoinHandle, scope, Builder, Park, current
│ ├── time/ # Instant, SystemTime, Duration is in core
│ ├── sync/
│ │ ├── mutex.rs
│ │ ├── rwlock.rs
│ │ ├── condvar.rs
│ │ ├── once.rs # Once, OnceLock, OnceCell
│ │ ├── mpmc/ # MPMC channels (newer)
│ │ ├── mpsc/ # MPSC channels (older API surface)
│ │ └── ...
│ ├── collections/
│ │ ├── hash/ # HashMap, HashSet (re-exports hashbrown)
│ │ └── ...
│ ├── path.rs # Path, PathBuf
│ ├── ffi/ # CString, CStr, OsStr, OsString
│ ├── panic.rs # std panic hooks, catch_unwind
│ ├── error.rs # Error trait
│ ├── backtrace.rs # Backtrace (re-exports backtrace crate)
│ ├── sys/ # Platform-conditional implementations
│ │ ├── pal/
│ │ │ ├── unix/ # All Unix variants
│ │ │ ├── windows/
│ │ │ ├── wasi/
│ │ │ ├── solid/
│ │ │ ├── hermit/
│ │ │ ├── teeos/
│ │ │ └── ...
│ │ ├── personality/ # Unwinding personality functions
│ │ └── ...
│ ├── os/ # OS-specific extension traits (Unix-/Windows-specific)
│ └── ...
└── tests/ # std's integration testsHow sys/ works
The library/std/src/sys/ directory is where platform conditionality lives. It's organized in PAL (Platform Abstraction Layer) style:
- The public std API is platform-independent (
std::fs::File,std::thread::spawn) - Each public function delegates to a
sysimplementation chosen bycfg(target_family = "unix" | "windows" | …) - Each platform's
sys/pal/<platform>/module implements the same internal trait surface
When you read File::open, you'll find it in library/std/src/fs.rs doing platform-independent work plus a call to sys::fs::File::open. That call resolves at compile time to a specific platform implementation under library/std/src/sys/pal/.
This is why std has heavy cfg(...) usage: every platform-conditional path needs to compile cleanly for every target, which means many #[cfg(unix)] mod unix; #[cfg(windows)] mod windows; patterns at the top of files.
Key abstractions
| Type | Where | Notes |
|---|---|---|
File |
std::fs |
Platform-conditional handle |
Command / Child |
std::process |
Process spawning |
TcpStream, UdpSocket |
std::net |
BSD-socket wrappers |
Mutex<T> |
std::sync::mutex |
Built on sys::Mutex (futex on Linux, SRWLOCK on Windows) |
RwLock<T> |
std::sync::rwlock |
Reader-writer lock |
OnceLock<T> |
std::sync::once_lock |
Lazy initialization, thread-safe |
JoinHandle<T> |
std::thread |
Owns a thread; .join() waits for it |
HashMap<K, V> |
std::collections::hash_map |
Wraps hashbrown |
Path, PathBuf |
std::path |
OS-aware path manipulation |
OsStr, OsString |
std::ffi |
OS-native strings |
Backtrace |
std::backtrace |
Lazy backtrace capture |
Stdin, Stdout, Stderr |
std::io |
Standard streams |
Collections
std::collections re-exports Vec, BTreeMap, etc. from alloc and adds hash-based collections:
HashMap<K, V>—library/std/src/collections/hash/map.rs. Wraps thehashbrowncrate (vendored as part of std's build) with Rust's defaultRandomStatehasher.HashSet<T>— same.
The default hasher is RandomState, which uses SipHash seeded with a per-process random value — DoS-resistant. Custom hashers are supported via the BuildHasher trait.
Panicking and unwinding
std::panic provides:
set_hook/take_hook— the panic hookcatch_unwind— converts panics intoResult::Err(Box<dyn Any>)(for FFI boundaries)resume_unwindLocation,PanicInfo
Unwinding itself happens via library/panic_unwind/ (or library/panic_abort/ for panic = "abort" builds). panic_unwind calls into library/unwind/ which wraps the platform unwinder (libgcc_s / libunwind / Windows SEH).
I/O
std::io provides traits (Read, Write, BufRead, Seek) and the implementations on file/socket/process types. Standard streams (Stdin, Stdout, Stderr) are line-buffered by default for Stdout (when connected to a terminal). The locking model is per-handle: Stdout::lock() returns a StdoutLock for atomic write_alls.
std::io::BufReader and BufWriter are general-purpose buffering wrappers. BufRead is the trait that adds read_line, read_until, etc.
Time
std::time::Instant is monotonic — it never goes backwards, even if the wall clock changes. std::time::SystemTime is wall-clock time. Duration is in core::time (it doesn't need an OS).
Threads and std::thread::scope
std::thread::spawn returns a JoinHandle<T> which owns the thread — drop without joining and the thread becomes detached. std::thread::scope (stable since 1.63) lets threads borrow non-'static data:
std::thread::scope(|s| {
let v = vec![1, 2, 3];
s.spawn(|| { for x in &v { ... } });
}); // all spawned threads joined before this block exitsImplementation lives in library/std/src/thread/scoped.rs.
Synchronization primitives
std::sync::Mutex<T>, RwLock<T>, Condvar, Barrier, Once, OnceLock<T> — built on platform primitives in sys. On Linux they're implemented with futexes for both speed and static-friendly construction. The Windows backend uses SRWLOCK + CONDITION_VARIABLE.
OnceLock<T> is the modern building block for lazy globals. The older Once and lazy_static!-style patterns are largely obsolete.
Async runtime — not in std
There is no async runtime in std. Async/await is a language feature (lowering happens in the compiler), Future lives in core, and runtimes (Tokio, async-std, smol) live in third-party crates.
std does provide:
Future(re-exported fromcore::future)noop_waker(stable noopWaker)- That's mostly it
Entry points for modification
- Bug in
std::fs/std::net/std::process→ likely in the relevantlibrary/std/src/sys/pal/<platform>/file - New method on a public type → ACP first; then add
#[unstable]and the unit test - Performance work in
Mutex/RwLock→ benchmark on multiple platforms - New target support →
library/std/src/sys/pal/<new_platform>/plus a target spec incompiler/rustc_target/src/spec/
See also
core— the#![no_std]foundationalloc— heap-allocated containers- Other runtime crates —
panic_unwind,unwind,compiler-builtins - The std-dev-guide — internal contributor docs
- The Rust API guidelines
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.