Skip to main content
This glossary provides definitions for terms commonly used in the Rust compiler, language specifications, and development ecosystem.

A

An argument-position impl Trait, also known as an anonymous type parameter.
fn process(item: impl Display) {
    println!("Processing: {}", item);
}
Equivalent to a generic parameter but more concise for simple cases.
A large memory buffer from which other memory allocations are made. This allocation strategy improves performance by:
  • Reducing allocation overhead
  • Enabling bulk deallocation
  • Improving cache locality
The compiler uses arenas extensively to manage AST and HIR data structures.
The abstract syntax tree produced by the rustc_ast crate that closely reflects user syntax. It’s the first major representation of code after parsing.Example: The code let x = 5; is parsed into an AST node representing a let-binding with pattern x and expression 5.

B

A place where a variable or type is declared. Examples:
  • <T> in fn foo<T>(..) is a binder for generic type parameter T
  • |a| in a closure is a binder for parameter a
An identifier that refers to a specific body (definition of a function or constant) in the crate. Used internally by the compiler to reference function implementations.
A variable declared within an expression or term. In the closure |a| a * 2, the variable a is bound.Contrast with: Free variables, which are used but not declared within the expression.

C

The process of translating MIR (Mid-level Intermediate Representation) into LLVM IR for final compilation to machine code.Pipeline: HIR → MIR → LLVM IR → Machine Code
When producing LLVM IR, Rust code is grouped into codegen units. Each unit:
  • Is processed by LLVM independently (enables parallelism)
  • Serves as the unit of incremental reuse
  • Can be controlled with compiler flags for optimization
A representation of the control flow in a program, showing all paths that might be traversed during execution. Used for:
  • Dataflow analysis
  • Optimization passes
  • Borrow checking
The compiler’s ability to evaluate const fn functions at compile time.
const fn square(x: i32) -> i32 {
    x * x
}

const RESULT: i32 = square(5); // Evaluated at compile time
Part of Rust’s constant evaluation system.
Common abbreviations for “context” in the compiler:
  • cx: Generic context
  • tcx: Typing context (TyCtxt), the main compiler data structure
  • infcx: Type inference context (InferCtxt)

D

Used during compilation to track dependencies between queries in the query system. Ensures no circular dependencies exist.
A static analysis technique that determines what properties hold true at each point in a program’s control flow. Used for:
  • Borrow checking
  • Initialization analysis
  • Dead code detection
A technique for representing bound variables using only integers, making variable references independent of naming.Benefit: Invariant under variable renaming, simplifying compiler operations.
An index uniquely identifying a definition in the crate (function, type, constant, etc.). Fundamental to the compiler’s type system and name resolution.
The underlying value associated with an enum variant that indicates which variant is “active” at runtime.
enum Status {
    Success = 0,
    Error = 1,
}
// Discriminant values: 0 and 1
Not to be confused with variant index, which is internal to the compiler.
Compiler-generated code that handles calling destructors (Drop trait implementations) for data types when they go out of scope.
A type whose size cannot be known at compile time.Examples:
  • str (string slice)
  • [T] (slice)
  • Trait objects like dyn Display
Restrictions:
  • Must be behind a pointer (&str, Box<dyn Display>)
  • Can only be the last field in a struct
  • Cannot be allocated on the stack directly
  • Don’t implement Sized trait

E

A lifetime region substituted at its definition site. Bound in an item’s Generics and substituted using GenericArgs.Contrast with: Late-bound lifetime (substituted at call site)
Currently refers to const traits and ~const bounds, allowing trait bounds to be used in const contexts.

F

A two-word pointer carrying:
  1. The address of the value
  2. Additional metadata
Types of fat pointers:
  • Slice references (&[T]): address + length
  • Trait objects (&dyn Trait): address + vtable pointer
let slice: &[i32] = &[1, 2, 3];
// Fat pointer: [data_ptr, length: 3]

let trait_obj: &dyn Display = &"hello";
// Fat pointer: [data_ptr, vtable_ptr]
A variable used in an expression but not declared (bound) within it. Commonly seen in closures.
let x = 5;
let closure = || x + 1; // x is a free variable (captured)

G

The list of generic parameters defined on an item. Three kinds:
  1. Type parameters: <T>
  2. Lifetime parameters: <'a>
  3. Const parameters: <const N: usize>
fn process<'a, T: Display, const N: usize>(items: &'a [T; N]) {
    // 'a: lifetime, T: type, N: const
}

H

Created by lowering and desugaring the AST. More suitable for type checking and analysis than the AST.Transformation: Source Code → AST → HIR → MIR → LLVM IR
Identifies a particular node in the HIR by combining a def-id with an “intra-definition offset”.

I

When the compiler crashes unexpectedly. These are considered bugs in the compiler.
If you encounter an ICE, please report it at github.com/rust-lang/rust/issues
Fingerprints (hashes) for HIR, crate metadata, and other compiler artifacts. Used to detect changes and enable incremental compilation.
A special type/region/const representing an unknown value during type inference. Think of it as “X” in algebra.Example: When inferring let x = vec![];, the compiler creates an inference variable for the vector’s element type.
Storing frequently-used constant data (like strings) once and referring to it by identifier rather than copying it repeatedly.Benefits:
  • Reduced memory usage
  • Fewer allocations
  • Fast equality comparisons (compare identifiers, not content)
The heart of const evaluation, executing MIR code at compile time to compute constant values.
Special functions implemented in the compiler itself but exposed to users (often as unstable features). They perform “magical” low-level operations.Examples:
  • std::intrinsics::transmute
  • SIMD operations
  • Atomic operations
Intrinsics are often unsafe and unstable. Use with caution.
A general compiler term for transformed code representations between source and machine code.Rust’s IRs:
  1. AST - Reflects source syntax
  2. HIR - Desugared, suitable for type checking
  3. MIR - Control-flow graph, suitable for borrow checking
  4. LLVM IR - Low-level, suitable for optimization and codegen

L

Items representing concepts intrinsic to the language itself.Examples:
  • Built-in traits: Sync, Send, Copy
  • Operator traits: Add, Deref
  • Special types: Box, String
  • Compiler-called functions
Marked with #[lang = "..."] attribute.
A lifetime region substituted at its call site. Used in Higher-Rank Trait Bounds (HRTB).
fn apply<F>(f: F) 
where 
    F: for<'a> Fn(&'a str) -> &'a str
{
    // 'a is late-bound
}
Contrast with: Early-bound lifetime
An open-source compiler backend that accepts LLVM IR and outputs native binaries. Rust compiles to LLVM IR, enabling support for all platforms LLVM supports.
The crate currently being compiled. Contrast with: Upstream crates (dependencies).

M

Storing results of pure computations to avoid repeating them. Trade-off between execution speed and memory usage.Used extensively in the compiler’s query system.
Created after type-checking, used for borrow checking and codegen. Represents code as a control-flow graph with basic blocks.Advantages:
  • Easier to analyze than HIR
  • Explicit control flow
  • Suitable for optimizations
An interpreter for Rust’s MIR that can detect Undefined Behavior in unsafe code.
cargo +nightly miri test
Extremely useful for validating unsafe code correctness.
The process of creating concrete implementations from generic code.
fn generic<T>(x: T) -> T { x }

let _a = generic(5i32);     // Generates generic::<i32>
let _b = generic("hello");  // Generates generic::<&str>
Each generic instantiation gets its own machine code copy.

N

A wrapper around another type, usually a single-field tuple struct.
struct UserId(u64);
struct Meters(f64);
Benefits:
  • Type safety (can’t mix up UserId and other u64s)
  • Zero runtime cost
  • Can implement traits specifically for the newtype
Invalid bit patterns for a type that can be used for layout optimizations.Example: Option<&T> uses the same size as &T because &T cannot be null (null is the niche representing None).
assert_eq!(
    std::mem::size_of::<Option<&i32>>(),
    std::mem::size_of::<&i32>()
);
An extension to Rust’s borrowing system making lifetimes based on control-flow graph rather than lexical scopes.Enables code like:
let mut x = 5;
let y = &x;      // borrow starts
println!("{}", y); // borrow ends here (last use)
x = 6;           // OK! No longer borrowed
An index identifying a node in the AST or HIR. Being gradually replaced by HirId.

O

Something that must be proven by the trait system during type checking.Example: When you call a generic function with a trait bound, the compiler creates an obligation to prove that bound is satisfied.

P

A way of handling subtyping around “for-all” types. Replaced the older skolemization approach.Used for higher-ranked trait bounds and lifetime inference.
In NLL analysis, a location in the MIR, typically a node in the control-flow graph.
A “relative path” to a type or value:
  • Field projection: x.field
  • Associated type projection: T::Item, <Vec<T> as IntoIterator>::Item
The function that executes a query in the query system.

Q

In type theory, asking questions with existential (∃) or universal (∀) quantifiers:
  • Existential: “Is there any type T for which this is true?”
  • Universal: “Is this true for all types T?”
Example: for<'a> fn(&'a str) uses universal quantification over lifetime 'a.
A sub-computation during compilation whose results can be cached (memoized).Examples:
  • type_of(DefId) - Get the type of a definition
  • mir_built(DefId) - Get the MIR for a function
Enables incremental compilation and parallelization.

R

Handling invalid syntax during parsing and continuing to parse. Avoids cascading spurious errors.Example: If a struct definition has a syntax error, the parser recovers and continues, avoiding “missing field” errors that would be misleading.
Another term for “lifetime,” commonly used in academic literature and the borrow checker implementation.
A data structure in name resolution tracking a single scope for names. Ribs form a stack representing nested scopes.
Using impl Trait in return position.
fn returns_iterator() -> impl Iterator<Item = i32> {
    vec![1, 2, 3].into_iter()
}
Creates an opaque type known only to the function.
Using impl Trait in trait method return types. Desugared to a generic associated type (GAT).
trait Container {
    fn iter(&self) -> impl Iterator<Item = i32>;
}

S

The expression matched in pattern matching constructs.
match expression {  // 'expression' is the scrutinee
    Pattern1 => ...,
    Pattern2 => ...,
}
The compiler session storing global data used throughout compilation. Accessed via tcx.sess.
Hashtables storing extra information about AST/HIR nodes (which are immutable). Indexed by node ID.Examples: Type information, resolution data, lint levels.
A keyword-like symbol composed of non-alphanumeric characters.Examples:
  • & - reference sigil
  • * - dereference/raw pointer sigil
  • ! - macro sigil
A type system property: if a program type-checks, it is type-safe and cannot cause undefined behavior in safe code.Rust’s guarantee: Safe Rust is sound (cannot cause UB without unsafe).
A location in source code used for error reporting. Contains:
  • File name
  • Start and end positions
  • Macro expansion tracking
  • Compiler desugaring information
All while being compactly stored.
Replacing generic parameters with concrete types.Modern terminology: “Instantiation” or “generic arguments”
HashMap<String, i32>  // i32, String are substitutions/generic args
The directory containing build artifacts loaded by the compiler at runtime (standard library, core, etc.).View with: rustc --print sysroot

T

Encodes the discriminant of an active enum variant or generator state. Can be:
  • Direct: Stored in a dedicated field
  • Niche-based: Uses invalid bit patterns of other fields
Defining opaque types with type aliases.
type MyIter = impl Iterator<Item = i32>;

fn get_iter() -> MyIter {
    vec![1, 2, 3].into_iter()
}
Standard variable name for TyCtxt, the main compiler data structure providing access to:
  • Session data
  • Query system
  • Type information
  • HIR/MIR
The lifetime of the compiler’s main allocation arena. Most interned data uses this lifetime.
Variables where each thread has its own copy. Used in the compiler for thread-specific state.
Not all platforms support TLS. Can affect target support.
The smallest unit of parsing, produced after lexing.Examples: Keywords (fn, let), literals (42, "hello"), operators (+, ->), delimiters ({, }).
A trait name with concrete generic arguments.
Display              // Trait reference with no args
Iterator<Item = i32> // Trait reference with associated type
Fn(i32) -> bool      // Trait reference (Fn is a trait)
Deprecated term. Now called codegen. Referred to translating MIR to LLVM IR.
The internal representation of a type in the compiler. Found in rustc_middle::ty.
The central data structure (tcx) providing access to all compiler state and the query system.

U

Deprecated term. Now called “fully-qualified syntax.”
Trait::method(&value)           // Qualified
<Type as Trait>::method(&value) // Fully-qualified
A type with no values whatsoever.Examples:
enum Never {}  // No variants = no values
let x: !;      // Never type
Not the same as ZST: ZST has exactly one value; uninhabited types have zero.Code dealing with uninhabited types can be treated as dead code.
A variable captured by a closure from outside the closure.
let x = 5;
let closure = || x + 1;  // x is an upvar

V

How changes to generic parameters affect subtyping.Types:
  • Covariant: Vec<T> is covariant in T (if T: U, then Vec<T>: Vec<U>)
  • Contravariant: Fn(T) is contravariant in T
  • Invariant: &mut T is invariant in T
Internal compiler identifier for enum variants (0, 1, 2, …). Not to be confused with user-visible discriminants.

W

A type or construct that follows the rules of the type system.Examples of well-formed types:
  • Vec<i32>
  • &'a T where T: 'a
Not well-formed:
  • Vec (missing generic argument) ✗

Z

A type whose values have size 0 bytes. Since 2^0 = 1, such types have exactly one value.Examples:
struct Unit;     // ZST
struct Empty {}  // ZST
let x = ();      // () is a ZST
Compiler optimizations: ZSTs can be optimized away entirely, no memory allocation needed.
A Vec<()> only stores its length, not the actual () values!

Build docs developers (and LLMs) love