Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Generics, Traits, and API Boundaries

rust-analyzer uses traits differently at each architectural layer.

Parser traits such as TokenSource and TreeSink keep the grammar generic over token and tree representations. Salsa’s Database trait is passed as &dyn salsa::Database through query-heavy compiler internals, giving generated query machinery one database boundary without parameterizing every HIR type.

RequestDispatcher::on<R> is generic over R: lsp_types::Request. Associated Params and Result types make mismatched handlers impossible, while const generic retry policy records cancellation behavior at the call site.

The public ide API deliberately exposes concrete POD-like domain values and an Analysis snapshot. HIR provides an object-oriented façade over ID-oriented internals. Closed variations—events, tasks, syntax kinds, completion kinds—use enums for exhaustive handling. Heterogeneous worker functions and VFS handles use trait objects because they must occupy one queue or field.

Generics protect local type relationships; façades protect crate relationships. Both matter more here than saving dynamic-dispatch nanoseconds.