Open-Source Wikis

/

Rust

/

Library

/

`std`

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::ioRead, 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 tests

How 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 sys implementation chosen by cfg(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 the hashbrown crate (vendored as part of std's build) with Rust's default RandomState hasher.
  • 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 hook
  • catch_unwind — converts panics into Result::Err(Box<dyn Any>) (for FFI boundaries)
  • resume_unwind
  • Location, 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 exits

Implementation 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 from core::future)
  • noop_waker (stable noop Waker)
  • That's mostly it

Entry points for modification

  • Bug in std::fs/std::net/std::process → likely in the relevant library/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 in compiler/rustc_target/src/spec/

See also

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

`std` – Rust wiki | Factory