Features
Annotations
Source: annotations.rs
Provides user with annotations above items for looking up references or impl blocks and running/debugging binaries.
Auto Import
Source: auto_import.rs
Using the auto-import
assist it is possible to insert missing imports for unresolved items.
When inserting an import it will do so in a structured manner by keeping imports grouped,
separated by a newline in the following order:
std
andcore
- External Crates
- Current Crate, paths prefixed by
crate
- Current Module, paths prefixed by
self
- Super Module, paths prefixed by
super
Example:
use std::fs::File;
use itertools::Itertools;
use syntax::ast;
use crate::utils::insert_use;
use self::auto_import;
use super::AssistContext;
Import Granularity
It is possible to configure how use-trees are merged with the imports.granularity.group
setting.
It has the following configurations:
crate
: Merge imports from the same crate into a single use statement. This kind of nesting is only supported in Rust versions later than 1.24.module
: Merge imports from the same module into a single use statement.item
: Don't merge imports at all, creating one import per item.preserve
: Do not change the granularity of any imports. For auto-import this has the same effect asitem
.one
: Merge all imports into a single use statement as long as they have the same visibility and attributes.
In VS Code
the configuration for this is rust-analyzer.imports.granularity.group
.
Import Prefix
The style of imports in the same crate is configurable through the imports.prefix
setting.
It has the following configurations:
crate
: This setting will force paths to be always absolute, starting with thecrate
prefix, unless the item is defined outside of the current crate.self
: This setting will force paths that are relative to the current module to always start withself
. This will result in paths that always start with eithercrate
,self
,super
or an extern crate identifier.plain
: This setting does not impose any restrictions in imports.
In VS Code
the configuration for this is rust-analyzer.imports.prefix
.
Completion With Autoimport
Source: flyimport.rs
When completing names in the current scope, proposes additional imports from other modules or crates, if they can be qualified in the scope, and their name contains all symbols from the completion input.
To be considered applicable, the name must contain all input symbols in the given order, not necessarily adjacent. If any input symbol is not lowercased, the name must contain all symbols in exact case; otherwise the containing is checked case-insensitively.
fn main() {
pda$0
}
# pub mod std { pub mod marker { pub struct PhantomData { } } }
->
use std::marker::PhantomData;
fn main() {
PhantomData
}
# pub mod std { pub mod marker { pub struct PhantomData { } } }
Also completes associated items, that require trait imports. If any unresolved and/or partially-qualified path precedes the input, it will be taken into account. Currently, only the imports with their import path ending with the whole qualifier will be proposed (no fuzzy matching for qualifier).
mod foo {
pub mod bar {
pub struct Item;
impl Item {
pub const TEST_ASSOC: usize = 3;
}
}
}
fn main() {
bar::Item::TEST_A$0
}
->
use foo::bar;
mod foo {
pub mod bar {
pub struct Item;
impl Item {
pub const TEST_ASSOC: usize = 3;
}
}
}
fn main() {
bar::Item::TEST_ASSOC
}
NOTE: currently, if an assoc item comes from a trait that's not currently imported, and it also has an unresolved and/or partially-qualified path, no imports will be proposed.
Fuzzy search details
To avoid an excessive amount of the results returned, completion input is checked for inclusion in the names only
(i.e. in HashMap
in the std::collections::HashMap
path).
For the same reasons, avoids searching for any path imports for inputs with their length less than 2 symbols
(but shows all associated items for any input length).
Import configuration
It is possible to configure how use-trees are merged with the imports.granularity.group
setting.
Mimics the corresponding behavior of the Auto Import
feature.
LSP and performance implications
The feature is enabled only if the LSP client supports LSP protocol version 3.16+ and reports the additionalTextEdits
(case-sensitive) resolve client capability in its client capabilities.
This way the server is able to defer the costly computations, doing them for a selected completion item only.
For clients with no such support, all edits have to be calculated on the completion request, including the fuzzy search completion ones,
which might be slow ergo the feature is automatically disabled.
Feature toggle
The feature can be forcefully turned off in the settings with the rust-analyzer.completion.autoimport.enable
flag.
Note that having this flag set to true
does not guarantee that the feature is enabled: your client needs to have the corresponding
capability enabled.
Debug ItemTree
Source: view_item_tree.rs
Displays the ItemTree of the currently open file, for debugging.
Editor | Action Name |
---|---|
VS Code | rust-analyzer: Debug ItemTree |
Expand Macro Recursively
Source: expand_macro.rs
Shows the full macro expansion of the macro at the current caret position.
Editor | Action Name |
---|---|
VS Code | rust-analyzer: Expand macro recursively at caret |
Expand and Shrink Selection
Source: extend_selection.rs
Extends or shrinks the current selection to the encompassing syntactic construct (expression, statement, item, module, etc). It works with multiple cursors.
Editor | Shortcut |
---|---|
VS Code | Alt+Shift+→, Alt+Shift+← |
File Structure
Source: file_structure.rs
Provides a tree of the symbols defined in the file. Can be used to
- fuzzy search symbol in a file (super useful)
- draw breadcrumbs to describe the context around the cursor
- draw outline of the file
Editor | Shortcut |
---|---|
VS Code | Ctrl+Shift+O |
Find All References
Source: references.rs
Shows all references of the item at the cursor location
Editor | Shortcut |
---|---|
VS Code | Shift+Alt+F12 |
Folding
Source: folding_ranges.rs
Defines folding regions for curly braced blocks, runs of consecutive use, mod, const or static
items, and region
/ endregion
comment markers.
Format String Completion
Source: format_like.rs
"Result {result} is {2 + 2}"
is expanded to the "Result {} is {}", result, 2 + 2
.
The following postfix snippets are available:
format
->format!(...)
panic
->panic!(...)
println
->println!(...)
log
: **logd
->log::debug!(...)
**logt
->log::trace!(...)
**logi
->log::info!(...)
**logw
->log::warn!(...)
**loge
->log::error!(...)
Go to Declaration
Source: goto_declaration.rs
Navigates to the declaration of an identifier.
This is the same as Go to Definition
with the following exceptions:
- outline modules will navigate to the
mod name;
item declaration - trait assoc items will navigate to the assoc item of the trait declaration as opposed to the trait impl
- fields in patterns will navigate to the field declaration of the struct, union or variant
Go to Definition
Source: goto_definition.rs
Navigates to the definition of an identifier.
For outline modules, this will navigate to the source file of the module.
Editor | Shortcut |
---|---|
VS Code | F12 |
Go to Implementation
Source: goto_implementation.rs
Navigates to the impl items of types.
Editor | Shortcut |
---|---|
VS Code | Ctrl+F12 |
Go to Type Definition
Source: goto_type_definition.rs
Navigates to the type of an identifier.
Editor | Action Name |
---|---|
VS Code | Go to Type Definition |
Highlight Related
Source: highlight_related.rs
Highlights constructs related to the thing under the cursor:
- if on an identifier, highlights all references to that identifier in the current file
- additionally, if the identifier is a trait in a where clause, type parameter trait bound or use item, highlights all references to that trait's assoc items in the corresponding scope
- if on an
async
orawait
token, highlights all yield points for that async context - if on a
return
orfn
keyword,?
character or->
return type arrow, highlights all exit points for that context - if on a
break
,loop
,while
orfor
token, highlights all break points for that loop or block context - if on a
move
or|
token that belongs to a closure, highlights all captures of the closure.
Note: ?
, |
and ->
do not currently trigger this behavior in the VSCode editor.
Hover
Source: hover.rs
Shows additional information, like the type of an expression or the documentation for a definition when "focusing" code. Focusing is usually hovering with a mouse, but can also be triggered with a shortcut.
Inlay Hints
Source: inlay_hints.rs
rust-analyzer shows additional information inline with the source code. Editors usually render this using read-only virtual text snippets interspersed with code.
rust-analyzer by default shows hints for
- types of local variables
- names of function arguments
- names of const generic parameters
- types of chained expressions
Optionally, one can enable additional hints for
- return types of closure expressions
- elided lifetimes
- compiler inserted reborrows
- names of generic type and lifetime parameters
Note: inlay hints for function argument names are heuristically omitted to reduce noise and will not appear if any of the following criteria are met:
- the parameter name is a suffix of the function's name
- the argument is a qualified constructing or call expression where the qualifier is an ADT
- exact argument<->parameter match(ignoring leading underscore) or parameter is a prefix/suffix of argument with _ splitting it off
- the parameter name starts with
ra_fixture
- the parameter name is a well known name in a unary function
- the parameter name is a single character in a unary function
Interpret A Function, Static Or Const.
Source: interpret.rs
Editor | Action Name |
---|---|
VS Code | rust-analyzer: Interpret |
Join Lines
Source: join_lines.rs
Join selected lines into one, smartly fixing up whitespace, trailing commas, and braces.
See this gif for the cases handled specially by joined lines.
Editor | Action Name |
---|---|
VS Code | rust-analyzer: Join lines |
Magic Completions
Source: lib.rs
In addition to usual reference completion, rust-analyzer provides some ✨magic✨ completions as well:
Keywords like if
, else
while
, loop
are completed with braces, and cursor
is placed at the appropriate position. Even though if
is easy to type, you
still want to complete it, to get { }
for free! return
is inserted with a
space or ;
depending on the return type of the function.
When completing a function call, ()
are automatically inserted. If a function
takes arguments, the cursor is positioned inside the parenthesis.
There are postfix completions, which can be triggered by typing something like
foo().if
. The word after .
determines postfix completion. Possible variants are:
expr.if
->if expr {}
orif let ... {}
forOption
orResult
expr.match
->match expr {}
expr.while
->while expr {}
orwhile let ... {}
forOption
orResult
expr.ref
->&expr
expr.refm
->&mut expr
expr.let
->let $0 = expr;
expr.lete
->let $1 = expr else { $0 };
expr.letm
->let mut $0 = expr;
expr.not
->!expr
expr.dbg
->dbg!(expr)
expr.dbgr
->dbg!(&expr)
expr.call
->(expr)
There also snippet completions:
Expressions
pd
->eprintln!(" = {:?}", );
ppd
->eprintln!(" = {:#?}", );
Items
tfn
->#[test] fn feature(){}
tmod
->
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_name() {}
}
And the auto import completions, enabled with the rust-analyzer.completion.autoimport.enable
setting and the corresponding LSP client capabilities.
Those are the additional completion options with automatic use
import and options from all project importable items,
fuzzy matched against the completion input.
Matching Brace
Source: matching_brace.rs
If the cursor is on any brace (<>(){}[]||
) which is a part of a brace-pair,
moves cursor to the matching brace. It uses the actual parser to determine
braces, so it won't confuse generics with comparisons.
Editor | Action Name |
---|---|
VS Code | rust-analyzer: Find matching brace |
Memory Usage
Source: apply_change.rs
Clears rust-analyzer's internal database and prints memory usage statistics.
Editor | Action Name |
---|---|
VS Code | rust-analyzer: Memory Usage (Clears Database) |
Move Item
Source: move_item.rs
Move item under cursor or selection up and down.
Editor | Action Name |
---|---|
VS Code | rust-analyzer: Move item up |
VS Code | rust-analyzer: Move item down |
On Enter
Source: on_enter.rs
rust-analyzer can override Enter key to make it smarter:
- Enter inside triple-slash comments automatically inserts
///
- Enter in the middle or after a trailing space in
//
inserts//
- Enter inside
//!
doc comments automatically inserts//!
- Enter after
{
indents contents and closing}
of single-line block
This action needs to be assigned to shortcut explicitly.
Note that, depending on the other installed extensions, this feature can visibly slow down typing.
Similarly, if rust-analyzer crashes or stops responding, Enter
might not work.
In that case, you can still press Shift-Enter
to insert a newline.
VS Code
Add the following to keybindings.json
:
{
"key": "Enter",
"command": "rust-analyzer.onEnter",
"when": "editorTextFocus && !suggestWidgetVisible && editorLangId == rust"
}
When using the Vim plugin:
{
"key": "Enter",
"command": "rust-analyzer.onEnter",
"when": "editorTextFocus && !suggestWidgetVisible && editorLangId == rust && vim.mode == 'Insert'"
}
On Typing Assists
Source: typing.rs
Some features trigger on typing certain characters:
- typing
let =
tries to smartly add;
if=
is followed by an existing expression - typing
=
between two expressions adds;
when in statement position - typing
=
to turn an assignment into an equality comparison removes;
when in expression position - typing
.
in a chain method call auto-indents - typing
{
or(
in front of an expression inserts a closing}
or)
after the expression - typing
{
in a use item adds a closing}
in the right place - typing
>
to complete a return type->
will insert a whitespace after it
VS Code
Add the following to settings.json
:
"editor.formatOnType": true,
Open Docs
Source: doc_links.rs
Retrieve a links to documentation for the given symbol.
The simplest way to use this feature is via the context menu. Right-click on the selected item. The context menu opens. Select Open Docs.
Editor | Action Name |
---|---|
VS Code | rust-analyzer: Open Docs |
Parent Module
Source: parent_module.rs
Navigates to the parent module of the current module.
Editor | Action Name |
---|---|
VS Code | rust-analyzer: Locate parent module |
Related Tests
Source: runnables.rs
Provides a sneak peek of all tests where the current item is used.
The simplest way to use this feature is via the context menu. Right-click on the selected item. The context menu opens. Select Peek Related Tests.
Editor | Action Name |
---|---|
VS Code | rust-analyzer: Peek Related Tests |
Rename
Source: rename.rs
Renames the item below the cursor and all of its references
Editor | Shortcut |
---|---|
VS Code | F2 |
Run
Source: runnables.rs
Shows a popup suggesting to run a test/benchmark/binary at the current cursor location. Super useful for repeatedly running just a single test. Do bind this to a shortcut!
Editor | Action Name |
---|---|
VS Code | rust-analyzer: Run |
Semantic Syntax Highlighting
Source: syntax_highlighting.rs
rust-analyzer highlights the code semantically.
For example, Bar
in foo::Bar
might be colored differently depending on whether Bar
is an enum or a trait.
rust-analyzer does not specify colors directly, instead it assigns a tag (like struct
) and a set of modifiers (like declaration
) to each token.
It's up to the client to map those to specific colors.
The general rule is that a reference to an entity gets colored the same way as the entity itself.
We also give special modifier for mut
and &mut
local variables.
Token Tags
Rust-analyzer currently emits the following token tags:
- For items:
attribute | Emitted for attribute macros. |
enum | Emitted for enums. |
function | Emitted for free-standing functions. |
derive | Emitted for derive macros. |
macro | Emitted for function-like macros. |
method | Emitted for associated functions, also knowns as methods. |
namespace | Emitted for modules. |
struct | Emitted for structs. |
trait | Emitted for traits. |
typeAlias | Emitted for type aliases and Self in impl s. |
union | Emitted for unions. |
- For literals:
boolean | Emitted for the boolean literals true and false . |
character | Emitted for character literals. |
number | Emitted for numeric literals. |
string | Emitted for string literals. |
escapeSequence | Emitted for escaped sequences inside strings like \n . |
formatSpecifier | Emitted for format specifiers {:?} in format! -like macros. |
- For operators:
operator | Emitted for general operators. |
arithmetic | Emitted for the arithmetic operators + , - , * , / , += , -= , *= , /= . |
bitwise | Emitted for the bitwise operators ` |
comparison | Emitted for the comparison oerators > , < , == , >= , <= , != . |
logical | Emitted for the logical operatos ` |
- For punctuation:
punctuation | Emitted for general punctuation. |
attributeBracket | Emitted for attribute invocation brackets, that is the #[ and ] tokens. |
angle | Emitted for <> angle brackets. |
brace | Emitted for {} braces. |
bracket | Emitted for [] brackets. |
parenthesis | Emitted for () parentheses. |
colon | Emitted for the : token. |
comma | Emitted for the , token. |
dot | Emitted for the . token. |
semi | Emitted for the ; token. |
macroBang | Emitted for the ! token in macro calls. |
builtinAttribute | Emitted for names to builtin attributes in attribute path, the repr in #[repr(u8)] for example. |
builtinType | Emitted for builtin types like u32 , str and f32 . |
comment | Emitted for comments. |
constParameter | Emitted for const parameters. |
deriveHelper | Emitted for derive helper attributes. |
enumMember | Emitted for enum variants. |
generic | Emitted for generic tokens that have no mapping. |
keyword | Emitted for keywords. |
label | Emitted for labels. |
lifetime | Emitted for lifetimes. |
parameter | Emitted for non-self function parameters. |
property | Emitted for struct and union fields. |
selfKeyword | Emitted for the self function parameter and self path-specifier. |
selfTypeKeyword | Emitted for the Self type parameter. |
toolModule | Emitted for tool modules. |
typeParameter | Emitted for type parameters. |
unresolvedReference | Emitted for unresolved references, names that rust-analyzer can't find the definition of. |
variable | Emitted for locals, constants and statics. |
Token Modifiers
Token modifiers allow to style some elements in the source code more precisely.
Rust-analyzer currently emits the following token modifiers:
async | Emitted for async functions and the async and await keywords. |
attribute | Emitted for tokens inside attributes. |
callable | Emitted for locals whose types implements one of the Fn* traits. |
constant | Emitted for const. |
consuming | Emitted for locals that are being consumed when use in a function call. |
controlFlow | Emitted for control-flow related tokens, this includes th ? operator. |
crateRoot | Emitted for crate names, like serde and `crate. |
declaration | Emitted for names of definitions, like foo in fn foo(){} . |
defaultLibrary | Emitted for items from built-in crates (std, core, allc, test and proc_macro). |
documentation | Emitted for documentation comment. |
injected | Emitted for doc-string injected highlighting like rust source blocks in documentation. |
intraDocLink | Emitted for intra doc links in doc-string. |
library | Emitted for items that are defined outside of the current crae. |
macro | Emitted for tokens inside macro call. |
mutable | Emitted for mutable locals and statics as well as functions taking &mut self . |
public | Emitted for items that are from the current crate and are `pub. |
reference | Emitted for locals behind a reference and functions taking self` by reference. |
static | Emitted for "static" functions, also known as functions that d not take a self param, as well as statics and consts. |
trait | Emitted for associated trait item. |
unsafe | Emitted for unsafe operations, like unsafe function calls, as ell as the unsafe token. |
Show Dependency Tree
Source: fetch_crates.rs
Shows a view tree with all the dependencies of this project
Editor | Panel Name |
---|---|
VS Code | Rust Dependencies |
Show Syntax Tree
Source: view_syntax_tree.rs
Shows a tree view with the syntax tree of the current file
Editor | Panel Name |
---|---|
VS Code | Rust Syntax Tree |
Status
Source: status.rs
Shows internal statistic about memory usage of rust-analyzer.
Editor | Action Name |
---|---|
VS Code | rust-analyzer: Status |
Structural Search and Replace
Source: lib.rs
Search and replace with named wildcards that will match any expression, type, path, pattern or item.
The syntax for a structural search replace command is <search_pattern> ==>> <replace_pattern>
.
A $<name>
placeholder in the search pattern will match any AST node and $<name>
will reference it in the replacement.
Within a macro call, a placeholder will match up until whatever token follows the placeholder.
All paths in both the search pattern and the replacement template must resolve in the context
in which this command is invoked. Paths in the search pattern will then match the code if they
resolve to the same item, even if they're written differently. For example if we invoke the
command in the module foo
with a pattern of Bar
, then code in the parent module that refers
to foo::Bar
will match.
Paths in the replacement template will be rendered appropriately for the context in which the
replacement occurs. For example if our replacement template is foo::Bar
and we match some
code in the foo
module, we'll insert just Bar
.
Inherent method calls should generally be written in UFCS form. e.g. foo::Bar::baz($s, $a)
will
match $s.baz($a)
, provided the method call baz
resolves to the method foo::Bar::baz
. When a
placeholder is the receiver of a method call in the search pattern (e.g. $s.foo()
), but not in
the replacement template (e.g. bar($s)
), then *, & and &mut will be added as needed to mirror
whatever autoderef and autoref was happening implicitly in the matched code.
The scope of the search / replace will be restricted to the current selection if any, otherwise it will apply to the whole workspace.
Placeholders may be given constraints by writing them as ${<name>:<constraint1>:<constraint2>...}
.
Supported constraints:
Constraint | Restricts placeholder |
---|---|
kind(literal) | Is a literal (e.g. 42 or "forty two" ) |
not(a) | Negates the constraint a |
Available via the command rust-analyzer.ssr
.
// Using structural search replace command [foo($a, $b) ==>> ($a).foo($b)]
// BEFORE
String::from(foo(y + 5, z))
// AFTER
String::from((y + 5).foo(z))
Editor | Action Name |
---|---|
VS Code | rust-analyzer: Structural Search Replace |
Also available as an assist, by writing a comment containing the structural search and replace rule. You will only see the assist if the comment can be parsed as a valid structural search and replace rule.
// Place the cursor on the line below to see the assist 💡.
// foo($a, $b) ==>> ($a).foo($b)
User Snippet Completions
Source: snippet.rs
rust-analyzer allows the user to define custom (postfix)-snippets that may depend on items to be accessible for the current scope to be applicable.
A custom snippet can be defined by adding it to the rust-analyzer.completion.snippets.custom
object respectively.
{
"rust-analyzer.completion.snippets.custom": {
"thread spawn": {
"prefix": ["spawn", "tspawn"],
"body": [
"thread::spawn(move || {",
"\t$0",
"});",
],
"description": "Insert a thread::spawn call",
"requires": "std::thread",
"scope": "expr",
}
}
}
In the example above:
-
"thread spawn"
is the name of the snippet. -
prefix
defines one or more trigger words that will trigger the snippets completion. Usingpostfix
will instead create a postfix snippet. -
body
is one or more lines of content joined via newlines for the final output. -
description
is an optional description of the snippet, if unset the snippet name will be used. -
requires
is an optional list of item paths that have to be resolvable in the current crate where the completion is rendered.
View Crate Graph
Source: view_crate_graph.rs
Renders the currently loaded crate graph as an SVG graphic. Requires the dot
tool, which
is part of graphviz, to be installed.
Only workspace crates are included, no crates.io dependencies or sysroot crates.
Editor | Action Name |
---|---|
VS Code | rust-analyzer: View Crate Graph |
View Hir
Source: view_hir.rs
Editor | Action Name |
---|---|
VS Code | rust-analyzer: View Hir |
View Memory Layout
Source: view_memory_layout.rs
Displays the recursive memory layout of a datatype.
Editor | Action Name |
---|---|
VS Code | rust-analyzer: View Memory Layout |
View Mir
Source: view_mir.rs
Editor | Action Name |
---|---|
VS Code | rust-analyzer: View Mir |
Workspace Symbol
Source: symbol_index.rs
Uses fuzzy-search to find types, modules and functions by name across your
project and dependencies. This is the most useful feature, which improves code
navigation tremendously. It mostly works on top of the built-in LSP
functionality, however #
and *
symbols can be used to narrow down the
search. Specifically,
Foo
searches forFoo
type in the current workspacefoo#
searches forfoo
function in the current workspaceFoo*
searches forFoo
type among dependencies, includingstdlib
foo#*
searches forfoo
function among dependencies
That is, #
switches from "types" to all symbols, *
switches from the current
workspace to dependencies.
Note that filtering does not currently work in VSCode due to the editor never
sending the special symbols to the language server. Instead, you can configure
the filtering via the rust-analyzer.workspace.symbol.search.scope
and
rust-analyzer.workspace.symbol.search.kind
settings. Symbols prefixed
with __
are hidden from the search results unless configured otherwise.
Editor | Shortcut |
---|---|
VS Code | Ctrl+T |