Rust by Example
Purpose and Scope
Rust by Example, often abbreviated RBE, is the example-first companion to Rust’s longer-form learning materials. Its reader problem is practical: many people learn a systems language by editing small programs, running them, and observing exactly what changes. The official RBE introduction presents it as a collection of runnable examples covering Rust concepts and standard libraries, with less prose than The Rust Programming Language book and with exercises for practice. In the documentation path, it is a good second view of a topic after reading a conceptual explanation, or a first view when the reader wants concrete code before theory.
RBE starts from the smallest executable program and then expands through primitives, custom types, bindings, type conversion, expressions, control flow, functions, modules, crates, Cargo, attributes, generics, scoping rules, traits, macros, and error handling. That sequence is intentionally broad rather than compiler-internal. However, many examples only work because Rust gives certain traits, operators, callable forms, panic hooks, and runtime functions special language meaning. In the compiler, those special concepts are represented as language items, or lang items, which map language-level names to definitions found in the current crate or dependencies.
Sources: compiler/rustc_hir/src/lang_items.rs, compiler/rustc_middle/src/middle/lang_items.rs
Learning Path
Use RBE as a runnable map of the language. A productive path is to begin with Hello World, then treat each chapter as a small laboratory: read the code, predict the output or diagnostic, run it, and then modify it. The official Learn page positions RBE as the option for readers who prefer seeing code over reading many pages, and also notes Rustlings as a command-line alternative. RBE therefore fits well between passive reading and project work: it gives enough context to recognize a feature, then asks you to build intuition through concrete examples.
When an example introduces operators, callable values, iterators, futures, or traits, remember that the surface syntax is not only library convention. The compiler has a table of valid lang items, including traits that specify kinds, traits that represent operators such as Add, Sub, and Index, and functions called by the compiler itself. That table lets compiler phases attach special meaning to library definitions without hard-coding every definition as ordinary syntax. For a learner, this explains why examples about traits and operators often feel like ordinary user code while still being deeply integrated into the language.
Sources: compiler/rustc_hir/src/lang_items.rs
RBE is also a useful way to practice transitions between language areas. For example, examples about functions and closures lead naturally to the Fn, FnMut, and FnOnce family; examples about asynchronous callable traits lead toward AsyncFn, AsyncFnMut, and AsyncFnOnce; and examples about iterators and futures introduce standard traits that appear throughout idiomatic Rust. The type context exposes helpers that map lang item definitions to closure kinds and test whether a definition is one of the built-in callable traits, reflecting the importance of these examples in real type checking.
Sources: compiler/rustc_middle/src/middle/lang_items.rs
Relevant Source Files
compiler/rustc_hir/src/lang_items.rs— definesLanguageItems, theLangItemenum table, lookup methods, reverse mapping fromDefIdto lang item, and metadata such as the#[lang = "..."]name associated with each compiler-recognized item.compiler/rustc_hir/src/weak_lang_items.rs— defines weak lang items such asPanicImplandEhPersonality, plus weak-only memory-related items, showing which compiler hooks may be linked by name rather than always required as ordinary definitions.compiler/rustc_middle/src/middle/lang_items.rs— addsTyCtxthelpers for requiring lang items, recognizing definitions as lang items, and mapping callable lang items to closure kinds used by type checking.compiler/rustc_passes/src/lang_items.rs— implements collection of lang items from attributes, target checks, duplicate detection, and integration with compiler query providers.compiler/rustc_passes/src/weak_lang_items.rs— checks whether weak lang items needed by the crate are present for emitted artifact types and reports missing panic or exception-personality support when required.compiler/rustc_type_ir/src/lang_items.rs— lists trait-solver-facing lang item categories for projections, ADTs, and traits, including items such asFuture,Iterator,Fn,Drop,Sized, andUnpin.
System-to-Code Mapping
At the documentation level, RBE examples are organized around visible Rust concepts. At the compiler level, the requested source files show how some of those concepts become stable internal handles. LanguageItems stores an array indexed by LangItem, a reverse map from DefId to LangItem, and a missing list for required items that were not found. This is not a tutorial API; it is the bridge that lets compiler passes say “the FnOnce trait” or “the panic implementation” after resolving the actual definition supplied by the standard library or another crate.
Sources: compiler/rustc_hir/src/lang_items.rs
The collection pass is the part that turns annotated definitions into that map. It scans attributes, extracts #[lang = "..."] names, validates the declared target, and records the matching LangItem when the definition is well formed. It also checks for duplicate lang items, because a single language concept must resolve to one definition for the compiler session. This matters to readers because RBE’s examples make traits, operators, and function calls feel uniform; internally, the compiler preserves that uniformity by enforcing a bijection between lang item names and definitions.
Sources: compiler/rustc_passes/src/lang_items.rs
Weak lang items are the exception-like edge of this system. Some hooks, such as the panic implementation or exception personality function, may be required only for certain output artifact types. The weak-lang-item check records missing weak items, inspects crate types, and emits targeted diagnostics such as missing panic handler or panic-unwind-without-std when an emitted binary-like artifact needs support that has not been provided. This is especially relevant after RBE’s basic examples if a reader later explores no_std, custom runtimes, or panic behavior.
Sources: compiler/rustc_hir/src/weak_lang_items.rs, compiler/rustc_passes/src/weak_lang_items.rs
The new trait solver uses a related but narrower vocabulary. Its lang item enums separate projection items, ADT items, and trait items, including Option, Poll, Future, Iterator, Drop, Clone, Copy, Sized, Unpin, and the callable traits. That split reflects a compiler architecture concern: solver code needs a representation of well-known language and library concepts without depending directly on every frontend detail. For learners, this reinforces that examples about traits and generics are not isolated syntax demonstrations; they exercise central machinery used by Rust’s type system.
Sources: compiler/rustc_type_ir/src/lang_items.rs
How to Use RBE with the Repository Context
When you work through RBE, do not try to read compiler sources chapter by chapter. Instead, use the examples to build surface fluency, then return to the repository when a feature raises an implementation question. If an operator example makes you wonder why a + b calls a trait method, look at the lang item table for operator traits. If a closure example makes you wonder how the compiler distinguishes Fn, FnMut, and FnOnce, look at the TyCtxt helpers that map those lang items to closure kinds. The source is most useful after the example has made the behavior concrete.
This also gives a healthy mental model for Rust’s standard library. Many RBE examples use APIs that look like ordinary library code, and most of them are. A small set of definitions, however, are designated by the compiler as intrinsic language concepts. That design lets Rust keep much of the language in libraries while still giving the compiler precise handles for type checking, method resolution, panic behavior, callable traits, and trait solving. RBE teaches the user-facing shape; the lang item files show how the implementation names the pieces that must be special.
Next Steps
After finishing an RBE chapter, run the example locally, change one line, and intentionally trigger a compiler error. Then use the Book for the conceptual explanation and the Reference when you need a more specification-oriented description. If your question is about how the compiler recognizes a trait, operator, callable form, panic hook, or solver concept, follow the source paths on this page. For broader context, continue to the language reference overview, standard library overview, unsafe Rust and Nomicon, or compiler architecture pages depending on whether your next question is about syntax, APIs, safety, or implementation.