Document not found (404)
+This URL is invalid, sorry. Please use the navigation bar or search to continue.
+ +diff --git a/docs/book/book/.nojekyll b/docs/book/book/.nojekyll new file mode 100644 index 000000000000..f17311098f54 --- /dev/null +++ b/docs/book/book/.nojekyll @@ -0,0 +1 @@ +This file makes sure that Github Pages doesn't process mdBook's output. diff --git a/docs/book/book/404.html b/docs/book/book/404.html new file mode 100644 index 000000000000..13bd1b2a8f66 --- /dev/null +++ b/docs/book/book/404.html @@ -0,0 +1,202 @@ + + +
+ + +This URL is invalid, sorry. Please use the navigation bar or search to continue.
+ +Assists, or code actions, are small local refactorings, available in a
+particular context. They are usually triggered by a shortcut or by
+clicking a light bulb icon in the editor. Cursor position or selection
+is signified by ┃
character.
add_braces
Source: add_braces.rs
+Adds braces to lambda and match arm expressions.
+fn foo(n: i32) -> i32 {
+ match n {
+ 1 =>┃ n + 1,
+ _ => 0
+ }
+}
+fn foo(n: i32) -> i32 {
+ match n {
+ 1 => {
+ n + 1
+ },
+ _ => 0
+ }
+}
+add_explicit_type
Source: add_explicit_type.rs
+Specify type for a let binding.
+fn main() {
+ let x┃ = 92;
+}
+fn main() {
+ let x: i32 = 92;
+}
+add_hash
Source: raw_string.rs
+Adds a hash to a raw string literal.
+fn main() {
+ r#"Hello,┃ World!"#;
+}
+fn main() {
+ r##"Hello, World!"##;
+}
+add_impl_default_members
Source: add_missing_impl_members.rs
+Adds scaffold for overriding default impl members.
+trait Trait {
+ type X;
+ fn foo(&self);
+ fn bar(&self) {}
+}
+
+impl Trait for () {
+ type X = ();
+ fn foo(&self) {}┃
+}
+trait Trait {
+ type X;
+ fn foo(&self);
+ fn bar(&self) {}
+}
+
+impl Trait for () {
+ type X = ();
+ fn foo(&self) {}
+
+ ┃fn bar(&self) {}
+}
+add_impl_missing_members
Source: add_missing_impl_members.rs
+Adds scaffold for required impl members.
+trait Trait<T> {
+ type X;
+ fn foo(&self) -> T;
+ fn bar(&self) {}
+}
+
+impl Trait<u32> for () {┃
+
+}
+trait Trait<T> {
+ type X;
+ fn foo(&self) -> T;
+ fn bar(&self) {}
+}
+
+impl Trait<u32> for () {
+ ┃type X;
+
+ fn foo(&self) -> u32 {
+ todo!()
+ }
+}
+add_label_to_loop
Source: add_label_to_loop.rs
+Adds a label to a loop.
+fn main() {
+ loop┃ {
+ break;
+ continue;
+ }
+}
+fn main() {
+ 'l: loop {
+ break 'l;
+ continue 'l;
+ }
+}
+add_lifetime_to_type
Source: add_lifetime_to_type.rs
+Adds a new lifetime to a struct, enum or union.
+struct Point {
+ x: &┃u32,
+ y: u32,
+}
+struct Point<'a> {
+ x: &'a u32,
+ y: u32,
+}
+add_missing_match_arms
Source: add_missing_match_arms.rs
+Adds missing clauses to a match
expression.
enum Action { Move { distance: u32 }, Stop }
+
+fn handle(action: Action) {
+ match action {
+ ┃
+ }
+}
+enum Action { Move { distance: u32 }, Stop }
+
+fn handle(action: Action) {
+ match action {
+ ┃Action::Move { distance } => todo!(),
+ Action::Stop => todo!(),
+ }
+}
+add_return_type
Source: add_return_type.rs
+Adds the return type to a function or closure inferred from its tail expression if it doesn't have a return +type specified. This assists is useable in a functions or closures tail expression or return type position.
+fn foo() { 4┃2i32 }
+fn foo() -> i32 { 42i32 }
+add_turbo_fish
Source: add_turbo_fish.rs
+Adds ::<_>
to a call of a generic method or function.
fn make<T>() -> T { todo!() }
+fn main() {
+ let x = make┃();
+}
+fn make<T>() -> T { todo!() }
+fn main() {
+ let x = make::<${0:_}>();
+}
+apply_demorgan
Source: apply_demorgan.rs
+Apply https://en.wikipedia.org/wiki/De_Morgan%27s_laws[De Morgan's law].
+This transforms expressions of the form !l || !r
into !(l && r)
.
+This also works with &&
. This assist can only be applied with the cursor
+on either ||
or &&
.
fn main() {
+ if x != 4 ||┃ y < 3.14 {}
+}
+fn main() {
+ if !(x == 4 && y >= 3.14) {}
+}
+apply_demorgan_iterator
Source: apply_demorgan.rs
+Apply https://en.wikipedia.org/wiki/De_Morgan%27s_laws[De Morgan's law] to
+Iterator::all
and Iterator::any
.
This transforms expressions of the form !iter.any(|x| predicate(x))
into
+iter.all(|x| !predicate(x))
and vice versa. This also works the other way for
+Iterator::all
into Iterator::any
.
fn main() {
+ let arr = [1, 2, 3];
+ if !arr.into_iter().┃any(|num| num == 4) {
+ println!("foo");
+ }
+}
+fn main() {
+ let arr = [1, 2, 3];
+ if arr.into_iter().all(|num| num != 4) {
+ println!("foo");
+ }
+}
+auto_import
Source: auto_import.rs
+If the name is unresolved, provides all possible imports for it.
+fn main() {
+ let map = HashMap┃::new();
+}
+use std::collections::HashMap;
+
+fn main() {
+ let map = HashMap::new();
+}
+bind_unused_param
Source: bind_unused_param.rs
+Binds unused function parameter to an underscore.
+fn some_function(x: i32┃) {}
+fn some_function(x: i32) {
+ let _ = x;
+}
+bool_to_enum
Source: bool_to_enum.rs
+This converts boolean local variables, fields, constants, and statics into a new
+enum with two variants Bool::True
and Bool::False
, as well as replacing
+all assignments with the variants and replacing all usages with == Bool::True
or
+== Bool::False
.
fn main() {
+ let ┃bool = true;
+
+ if bool {
+ println!("foo");
+ }
+}
+#[derive(PartialEq, Eq)]
+enum Bool { True, False }
+
+fn main() {
+ let bool = Bool::True;
+
+ if bool == Bool::True {
+ println!("foo");
+ }
+}
+change_visibility
Source: change_visibility.rs
+Adds or changes existing visibility specifier.
+┃fn frobnicate() {}
+pub(crate) fn frobnicate() {}
+convert_bool_then_to_if
Source: convert_bool_then.rs
+Converts a bool::then
method call to an equivalent if expression.
fn main() {
+ (0 == 0).then┃(|| val)
+}
+fn main() {
+ if 0 == 0 {
+ Some(val)
+ } else {
+ None
+ }
+}
+convert_for_loop_with_for_each
Source: convert_iter_for_each_to_for.rs
+Converts a for loop into a for_each loop on the Iterator.
+fn main() {
+ let x = vec![1, 2, 3];
+ for┃ v in x {
+ let y = v * 2;
+ }
+}
+fn main() {
+ let x = vec![1, 2, 3];
+ x.into_iter().for_each(|v| {
+ let y = v * 2;
+ });
+}
+convert_if_to_bool_then
Source: convert_bool_then.rs
+Converts an if expression into a corresponding bool::then
call.
fn main() {
+ if┃ cond {
+ Some(val)
+ } else {
+ None
+ }
+}
+fn main() {
+ cond.then(|| val)
+}
+convert_integer_literal
Source: convert_integer_literal.rs
+Converts the base of integer literals to other bases.
+const _: i32 = 10┃;
+const _: i32 = 0b1010;
+convert_into_to_from
Source: convert_into_to_from.rs
+Converts an Into impl to an equivalent From impl.
+impl ┃Into<Thing> for usize {
+ fn into(self) -> Thing {
+ Thing {
+ b: self.to_string(),
+ a: self
+ }
+ }
+}
+impl From<usize> for Thing {
+ fn from(val: usize) -> Self {
+ Thing {
+ b: val.to_string(),
+ a: val
+ }
+ }
+}
+convert_iter_for_each_to_for
Source: convert_iter_for_each_to_for.rs
+Converts an Iterator::for_each function into a for loop.
+fn main() {
+ let iter = iter::repeat((9, 2));
+ iter.for_each┃(|(x, y)| {
+ println!("x: {}, y: {}", x, y);
+ });
+}
+fn main() {
+ let iter = iter::repeat((9, 2));
+ for (x, y) in iter {
+ println!("x: {}, y: {}", x, y);
+ }
+}
+convert_let_else_to_match
Source: convert_let_else_to_match.rs
+Converts let-else statement to let statement and match expression.
+fn main() {
+ let Ok(mut x) = f() else┃ { return };
+}
+fn main() {
+ let mut x = match f() {
+ Ok(x) => x,
+ _ => return,
+ };
+}
+convert_match_to_let_else
Source: convert_match_to_let_else.rs
+Converts let statement with match initializer to let-else statement.
+fn foo(opt: Option<()>) {
+ let val┃ = match opt {
+ Some(it) => it,
+ None => return,
+ };
+}
+fn foo(opt: Option<()>) {
+ let Some(val) = opt else { return };
+}
+convert_named_struct_to_tuple_struct
Source: convert_named_struct_to_tuple_struct.rs
+Converts struct with named fields to tuple struct, and analogously for enum variants with named +fields.
+struct Point┃ { x: f32, y: f32 }
+
+impl Point {
+ pub fn new(x: f32, y: f32) -> Self {
+ Point { x, y }
+ }
+
+ pub fn x(&self) -> f32 {
+ self.x
+ }
+
+ pub fn y(&self) -> f32 {
+ self.y
+ }
+}
+struct Point(f32, f32);
+
+impl Point {
+ pub fn new(x: f32, y: f32) -> Self {
+ Point(x, y)
+ }
+
+ pub fn x(&self) -> f32 {
+ self.0
+ }
+
+ pub fn y(&self) -> f32 {
+ self.1
+ }
+}
+convert_nested_function_to_closure
Source: convert_nested_function_to_closure.rs
+Converts a function that is defined within the body of another function into a closure.
+fn main() {
+ fn fo┃o(label: &str, number: u64) {
+ println!("{}: {}", label, number);
+ }
+
+ foo("Bar", 100);
+}
+fn main() {
+ let foo = |label: &str, number: u64| {
+ println!("{}: {}", label, number);
+ };
+
+ foo("Bar", 100);
+}
+convert_to_guarded_return
Source: convert_to_guarded_return.rs
+Replace a large conditional with a guarded return.
+fn main() {
+ ┃if cond {
+ foo();
+ bar();
+ }
+}
+fn main() {
+ if !cond {
+ return;
+ }
+ foo();
+ bar();
+}
+convert_tuple_return_type_to_struct
Source: convert_tuple_return_type_to_struct.rs
+This converts the return type of a function from a tuple type +into a tuple struct and updates the body accordingly.
+fn bar() {
+ let (a, b, c) = foo();
+}
+
+fn foo() -> (┃u32, u32, u32) {
+ (1, 2, 3)
+}
+fn bar() {
+ let FooResult(a, b, c) = foo();
+}
+
+struct FooResult(u32, u32, u32);
+
+fn foo() -> FooResult {
+ FooResult(1, 2, 3)
+}
+convert_tuple_struct_to_named_struct
Source: convert_tuple_struct_to_named_struct.rs
+Converts tuple struct to struct with named fields, and analogously for tuple enum variants.
+struct Point┃(f32, f32);
+
+impl Point {
+ pub fn new(x: f32, y: f32) -> Self {
+ Point(x, y)
+ }
+
+ pub fn x(&self) -> f32 {
+ self.0
+ }
+
+ pub fn y(&self) -> f32 {
+ self.1
+ }
+}
+struct Point { field1: f32, field2: f32 }
+
+impl Point {
+ pub fn new(x: f32, y: f32) -> Self {
+ Point { field1: x, field2: y }
+ }
+
+ pub fn x(&self) -> f32 {
+ self.field1
+ }
+
+ pub fn y(&self) -> f32 {
+ self.field2
+ }
+}
+convert_two_arm_bool_match_to_matches_macro
Source: convert_two_arm_bool_match_to_matches_macro.rs
+Convert 2-arm match that evaluates to a boolean into the equivalent matches! invocation.
+fn main() {
+ match scrutinee┃ {
+ Some(val) if val.cond() => true,
+ _ => false,
+ }
+}
+fn main() {
+ matches!(scrutinee, Some(val) if val.cond())
+}
+convert_while_to_loop
Source: convert_while_to_loop.rs
+Replace a while with a loop.
+fn main() {
+ ┃while cond {
+ foo();
+ }
+}
+fn main() {
+ loop {
+ if !cond {
+ break;
+ }
+ foo();
+ }
+}
+destructure_tuple_binding
Source: destructure_tuple_binding.rs
+Destructures a tuple binding in place.
+fn main() {
+ let ┃t = (1,2);
+ let v = t.0;
+}
+fn main() {
+ let (┃_0, _1) = (1,2);
+ let v = _0;
+}
+desugar_doc_comment
Source: desugar_doc_comment.rs
+Desugars doc-comments to the attribute form.
+/// Multi-line┃
+/// comment
+#[doc = r"Multi-line
+comment"]
+expand_glob_import
Source: expand_glob_import.rs
+Expands glob imports.
+mod foo {
+ pub struct Bar;
+ pub struct Baz;
+}
+
+use foo::*┃;
+
+fn qux(bar: Bar, baz: Baz) {}
+mod foo {
+ pub struct Bar;
+ pub struct Baz;
+}
+
+use foo::{Bar, Baz};
+
+fn qux(bar: Bar, baz: Baz) {}
+extract_expressions_from_format_string
Source: extract_expressions_from_format_string.rs
+Move an expression out of a format string.
+fn main() {
+ print!("{var} {x + 1}┃");
+}
+fn main() {
+ print!("{var} {}"┃, x + 1);
+}
+extract_function
Source: extract_function.rs
+Extracts selected statements and comments into new function.
+fn main() {
+ let n = 1;
+ ┃let m = n + 2;
+ // calculate
+ let k = m + n;┃
+ let g = 3;
+}
+fn main() {
+ let n = 1;
+ fun_name(n);
+ let g = 3;
+}
+
+fn ┃fun_name(n: i32) {
+ let m = n + 2;
+ // calculate
+ let k = m + n;
+}
+extract_module
Source: extract_module.rs
+Extracts a selected region as separate module. All the references, visibility and imports are +resolved.
+┃fn foo(name: i32) -> i32 {
+ name + 1
+}┃
+
+fn bar(name: i32) -> i32 {
+ name + 2
+}
+mod modname {
+ pub(crate) fn foo(name: i32) -> i32 {
+ name + 1
+ }
+}
+
+fn bar(name: i32) -> i32 {
+ name + 2
+}
+extract_struct_from_enum_variant
Source: extract_struct_from_enum_variant.rs
+Extracts a struct from enum variant.
+enum A { ┃One(u32, u32) }
+struct One(u32, u32);
+
+enum A { One(One) }
+extract_type_alias
Source: extract_type_alias.rs
+Extracts the selected type as a type alias.
+struct S {
+ field: ┃(u8, u8, u8)┃,
+}
+type ┃Type = (u8, u8, u8);
+
+struct S {
+ field: Type,
+}
+extract_variable
Source: extract_variable.rs
+Extracts subexpression into a variable.
+fn main() {
+ ┃(1 + 2)┃ * 4;
+}
+fn main() {
+ let ┃var_name = (1 + 2);
+ var_name * 4;
+}
+fix_visibility
Source: fix_visibility.rs
+Makes inaccessible item public.
+mod m {
+ fn frobnicate() {}
+}
+fn main() {
+ m::frobnicate┃();
+}
+mod m {
+ ┃pub(crate) fn frobnicate() {}
+}
+fn main() {
+ m::frobnicate();
+}
+flip_binexpr
Source: flip_binexpr.rs
+Flips operands of a binary expression.
+fn main() {
+ let _ = 90 +┃ 2;
+}
+fn main() {
+ let _ = 2 + 90;
+}
+flip_comma
Source: flip_comma.rs
+Flips two comma-separated items.
+fn main() {
+ ((1, 2),┃ (3, 4));
+}
+fn main() {
+ ((3, 4), (1, 2));
+}
+flip_trait_bound
Source: flip_trait_bound.rs
+Flips two trait bounds.
+fn foo<T: Clone +┃ Copy>() { }
+fn foo<T: Copy + Clone>() { }
+generate_constant
Source: generate_constant.rs
+Generate a named constant.
+struct S { i: usize }
+impl S { pub fn new(n: usize) {} }
+fn main() {
+ let v = S::new(CAPA┃CITY);
+}
+struct S { i: usize }
+impl S { pub fn new(n: usize) {} }
+fn main() {
+ const CAPACITY: usize = ┃;
+ let v = S::new(CAPACITY);
+}
+generate_default_from_enum_variant
Source: generate_default_from_enum_variant.rs
+Adds a Default impl for an enum using a variant.
+enum Version {
+ Undefined,
+ Minor┃,
+ Major,
+}
+enum Version {
+ Undefined,
+ Minor,
+ Major,
+}
+
+impl Default for Version {
+ fn default() -> Self {
+ Self::Minor
+ }
+}
+generate_default_from_new
Source: generate_default_from_new.rs
+Generates default implementation from new method.
+struct Example { _inner: () }
+
+impl Example {
+ pub fn n┃ew() -> Self {
+ Self { _inner: () }
+ }
+}
+struct Example { _inner: () }
+
+impl Example {
+ pub fn new() -> Self {
+ Self { _inner: () }
+ }
+}
+
+impl Default for Example {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+generate_delegate_methods
Source: generate_delegate_methods.rs
+Generate delegate methods.
+struct Age(u8);
+impl Age {
+ fn age(&self) -> u8 {
+ self.0
+ }
+}
+
+struct Person {
+ ag┃e: Age,
+}
+struct Age(u8);
+impl Age {
+ fn age(&self) -> u8 {
+ self.0
+ }
+}
+
+struct Person {
+ age: Age,
+}
+
+impl Person {
+ ┃fn age(&self) -> u8 {
+ self.age.age()
+ }
+}
+generate_delegate_trait
Source: generate_delegate_trait.rs
+Generate delegate trait implementation for StructField
s.
trait SomeTrait {
+ type T;
+ fn fn_(arg: u32) -> u32;
+ fn method_(&mut self) -> bool;
+}
+struct A;
+impl SomeTrait for A {
+ type T = u32;
+
+ fn fn_(arg: u32) -> u32 {
+ 42
+ }
+
+ fn method_(&mut self) -> bool {
+ false
+ }
+}
+struct B {
+ a┃: A,
+}
+trait SomeTrait {
+ type T;
+ fn fn_(arg: u32) -> u32;
+ fn method_(&mut self) -> bool;
+}
+struct A;
+impl SomeTrait for A {
+ type T = u32;
+
+ fn fn_(arg: u32) -> u32 {
+ 42
+ }
+
+ fn method_(&mut self) -> bool {
+ false
+ }
+}
+struct B {
+ a: A,
+}
+
+impl SomeTrait for B {
+ type T = <A as SomeTrait>::T;
+
+ fn fn_(arg: u32) -> u32 {
+ <A as SomeTrait>::fn_(arg)
+ }
+
+ fn method_(&mut self) -> bool {
+ <A as SomeTrait>::method_( &mut self.a )
+ }
+}
+generate_deref
Source: generate_deref.rs
+Generate Deref
impl using the given struct field.
struct A;
+struct B {
+ ┃a: A
+}
+struct A;
+struct B {
+ a: A
+}
+
+impl core::ops::Deref for B {
+ type Target = A;
+
+ fn deref(&self) -> &Self::Target {
+ &self.a
+ }
+}
+generate_derive
Source: generate_derive.rs
+Adds a new #[derive()]
clause to a struct or enum.
struct Point {
+ x: u32,
+ y: u32,┃
+}
+#[derive(┃)]
+struct Point {
+ x: u32,
+ y: u32,
+}
+generate_doc_example
Source: generate_documentation_template.rs
+Generates a rustdoc example when editing an item's documentation.
+/// Adds two numbers.┃
+pub fn add(a: i32, b: i32) -> i32 { a + b }
+/// Adds two numbers.
+///
+/// # Examples
+///
+/// ```
+/// use test::add;
+///
+/// assert_eq!(add(a, b), );
+/// ```
+pub fn add(a: i32, b: i32) -> i32 { a + b }
+generate_documentation_template
Source: generate_documentation_template.rs
+Adds a documentation template above a function definition / declaration.
+pub struct S;
+impl S {
+ pub unsafe fn set_len┃(&mut self, len: usize) -> Result<(), std::io::Error> {
+ /* ... */
+ }
+}
+pub struct S;
+impl S {
+ /// Sets the length of this [`S`].
+ ///
+ /// # Errors
+ ///
+ /// This function will return an error if .
+ ///
+ /// # Safety
+ ///
+ /// .
+ pub unsafe fn set_len(&mut self, len: usize) -> Result<(), std::io::Error> {
+ /* ... */
+ }
+}
+generate_enum_as_method
Source: generate_enum_projection_method.rs
+Generate an as_
method for this enum variant.
enum Value {
+ Number(i32),
+ Text(String)┃,
+}
+enum Value {
+ Number(i32),
+ Text(String),
+}
+
+impl Value {
+ fn as_text(&self) -> Option<&String> {
+ if let Self::Text(v) = self {
+ Some(v)
+ } else {
+ None
+ }
+ }
+}
+generate_enum_is_method
Source: generate_enum_is_method.rs
+Generate an is_
method for this enum variant.
enum Version {
+ Undefined,
+ Minor┃,
+ Major,
+}
+enum Version {
+ Undefined,
+ Minor,
+ Major,
+}
+
+impl Version {
+ /// Returns `true` if the version is [`Minor`].
+ ///
+ /// [`Minor`]: Version::Minor
+ #[must_use]
+ fn is_minor(&self) -> bool {
+ matches!(self, Self::Minor)
+ }
+}
+generate_enum_try_into_method
Source: generate_enum_projection_method.rs
+Generate a try_into_
method for this enum variant.
enum Value {
+ Number(i32),
+ Text(String)┃,
+}
+enum Value {
+ Number(i32),
+ Text(String),
+}
+
+impl Value {
+ fn try_into_text(self) -> Result<String, Self> {
+ if let Self::Text(v) = self {
+ Ok(v)
+ } else {
+ Err(self)
+ }
+ }
+}
+generate_enum_variant
Source: generate_enum_variant.rs
+Adds a variant to an enum.
+enum Countries {
+ Ghana,
+}
+
+fn main() {
+ let country = Countries::Lesotho┃;
+}
+enum Countries {
+ Ghana,
+ Lesotho,
+}
+
+fn main() {
+ let country = Countries::Lesotho;
+}
+generate_from_impl_for_enum
Source: generate_from_impl_for_enum.rs
+Adds a From impl for this enum variant with one tuple field.
+enum A { ┃One(u32) }
+enum A { One(u32) }
+
+impl From<u32> for A {
+ fn from(v: u32) -> Self {
+ Self::One(v)
+ }
+}
+generate_function
Source: generate_function.rs
+Adds a stub function with a signature matching the function under the cursor.
+struct Baz;
+fn baz() -> Baz { Baz }
+fn foo() {
+ bar┃("", baz());
+}
+
+struct Baz;
+fn baz() -> Baz { Baz }
+fn foo() {
+ bar("", baz());
+}
+
+fn bar(arg: &str, baz: Baz) ${0:-> _} {
+ todo!()
+}
+
+generate_getter
Source: generate_getter_or_setter.rs
+Generate a getter method.
+struct Person {
+ nam┃e: String,
+}
+struct Person {
+ name: String,
+}
+
+impl Person {
+ fn ┃name(&self) -> &str {
+ self.name.as_ref()
+ }
+}
+generate_getter_mut
Source: generate_getter_or_setter.rs
+Generate a mut getter method.
+struct Person {
+ nam┃e: String,
+}
+struct Person {
+ name: String,
+}
+
+impl Person {
+ fn ┃name_mut(&mut self) -> &mut String {
+ &mut self.name
+ }
+}
+generate_impl
Source: generate_impl.rs
+Adds a new inherent impl for a type.
+struct Ctx┃<T: Clone> {
+ data: T,
+}
+struct Ctx<T: Clone> {
+ data: T,
+}
+
+impl<T: Clone> Ctx<T> {
+ ┃
+}
+generate_is_empty_from_len
Source: generate_is_empty_from_len.rs
+Generates is_empty implementation from the len method.
+struct MyStruct { data: Vec<String> }
+
+impl MyStruct {
+ #[must_use]
+ p┃ub fn len(&self) -> usize {
+ self.data.len()
+ }
+}
+struct MyStruct { data: Vec<String> }
+
+impl MyStruct {
+ #[must_use]
+ pub fn len(&self) -> usize {
+ self.data.len()
+ }
+
+ #[must_use]
+ pub fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+}
+generate_new
Source: generate_new.rs
+Adds a fn new
for a type.
struct Ctx<T: Clone> {
+ data: T,┃
+}
+struct Ctx<T: Clone> {
+ data: T,
+}
+
+impl<T: Clone> Ctx<T> {
+ fn ┃new(data: T) -> Self { Self { data } }
+}
+generate_setter
Source: generate_getter_or_setter.rs
+Generate a setter method.
+struct Person {
+ nam┃e: String,
+}
+struct Person {
+ name: String,
+}
+
+impl Person {
+ fn ┃set_name(&mut self, name: String) {
+ self.name = name;
+ }
+}
+generate_trait_from_impl
Source: generate_trait_from_impl.rs
+Generate trait for an already defined inherent impl and convert impl to a trait impl.
+struct Foo<const N: usize>([i32; N]);
+
+macro_rules! const_maker {
+ ($t:ty, $v:tt) => {
+ const CONST: $t = $v;
+ };
+}
+
+impl<const N: usize> Fo┃o<N> {
+ // Used as an associated constant.
+ const CONST_ASSOC: usize = N * 4;
+
+ fn create() -> Option<()> {
+ Some(())
+ }
+
+ const_maker! {i32, 7}
+}
+struct Foo<const N: usize>([i32; N]);
+
+macro_rules! const_maker {
+ ($t:ty, $v:tt) => {
+ const CONST: $t = $v;
+ };
+}
+
+trait ${0:TraitName}<const N: usize> {
+ // Used as an associated constant.
+ const CONST_ASSOC: usize = N * 4;
+
+ fn create() -> Option<()>;
+
+ const_maker! {i32, 7}
+}
+
+impl<const N: usize> ${0:TraitName}<N> for Foo<N> {
+ // Used as an associated constant.
+ const CONST_ASSOC: usize = N * 4;
+
+ fn create() -> Option<()> {
+ Some(())
+ }
+
+ const_maker! {i32, 7}
+}
+generate_trait_impl
Source: generate_impl.rs
+Adds a new trait impl for a type.
+struct ┃Ctx<T: Clone> {
+ data: T,
+}
+struct Ctx<T: Clone> {
+ data: T,
+}
+
+impl<T: Clone> ┃ for Ctx<T> {
+
+}
+inline_call
Source: inline_call.rs
+Inlines a function or method body creating a let
statement per parameter unless the parameter
+can be inlined. The parameter will be inlined either if it the supplied argument is a simple local
+or if the parameter is only accessed inside the function body once.
fn foo(name: Option<&str>) {
+ let name = name.unwrap┃();
+}
+fn foo(name: Option<&str>) {
+ let name = match name {
+ Some(val) => val,
+ None => panic!("called `Option::unwrap()` on a `None` value"),
+ };
+}
+inline_const_as_literal
Source: inline_const_as_literal.rs
+Evaluate and inline const variable as literal.
+const STRING: &str = "Hello, World!";
+
+fn something() -> &'static str {
+ STRING┃
+}
+const STRING: &str = "Hello, World!";
+
+fn something() -> &'static str {
+ "Hello, World!"
+}
+inline_into_callers
Source: inline_call.rs
+Inline a function or method body into all of its callers where possible, creating a let
statement per parameter
+unless the parameter can be inlined. The parameter will be inlined either if it the supplied argument is a simple local
+or if the parameter is only accessed inside the function body once.
+If all calls can be inlined the function will be removed.
fn print(_: &str) {}
+fn foo┃(word: &str) {
+ if !word.is_empty() {
+ print(word);
+ }
+}
+fn bar() {
+ foo("안녕하세요");
+ foo("여러분");
+}
+fn print(_: &str) {}
+
+fn bar() {
+ {
+ let word = "안녕하세요";
+ if !word.is_empty() {
+ print(word);
+ }
+ };
+ {
+ let word = "여러분";
+ if !word.is_empty() {
+ print(word);
+ }
+ };
+}
+inline_local_variable
Source: inline_local_variable.rs
+Inlines a local variable.
+fn main() {
+ let x┃ = 1 + 2;
+ x * 4;
+}
+fn main() {
+ (1 + 2) * 4;
+}
+inline_macro
Source: inline_macro.rs
+Takes a macro and inlines it one step.
+macro_rules! num {
+ (+$($t:tt)+) => (1 + num!($($t )+));
+ (-$($t:tt)+) => (-1 + num!($($t )+));
+ (+) => (1);
+ (-) => (-1);
+}
+
+fn main() {
+ let number = num┃!(+ + + - + +);
+ println!("{number}");
+}
+macro_rules! num {
+ (+$($t:tt)+) => (1 + num!($($t )+));
+ (-$($t:tt)+) => (-1 + num!($($t )+));
+ (+) => (1);
+ (-) => (-1);
+}
+
+fn main() {
+ let number = 1+num!(+ + - + +);
+ println!("{number}");
+}
+inline_type_alias
Source: inline_type_alias.rs
+Replace a type alias with its concrete type.
+type A<T = u32> = Vec<T>;
+
+fn main() {
+ let a: ┃A;
+}
+type A<T = u32> = Vec<T>;
+
+fn main() {
+ let a: Vec<u32>;
+}
+inline_type_alias_uses
Source: inline_type_alias.rs
+Inline a type alias into all of its uses where possible.
+type ┃A = i32;
+fn id(x: A) -> A {
+ x
+};
+fn foo() {
+ let _: A = 3;
+}
+
+fn id(x: i32) -> i32 {
+ x
+};
+fn foo() {
+ let _: i32 = 3;
+}
+into_to_qualified_from
Source: into_to_qualified_from.rs
+Convert an into
method call to a fully qualified from
call.
//- minicore: from
+struct B;
+impl From<i32> for B {
+ fn from(a: i32) -> Self {
+ B
+ }
+}
+
+fn main() -> () {
+ let a = 3;
+ let b: B = a.in┃to();
+}
+struct B;
+impl From<i32> for B {
+ fn from(a: i32) -> Self {
+ B
+ }
+}
+
+fn main() -> () {
+ let a = 3;
+ let b: B = B::from(a);
+}
+introduce_named_generic
Source: introduce_named_generic.rs
+Replaces impl Trait
function argument with the named generic.
fn foo(bar: ┃impl Bar) {}
+fn foo<┃B: Bar>(bar: B) {}
+introduce_named_lifetime
Source: introduce_named_lifetime.rs
+Change an anonymous lifetime to a named lifetime.
+impl Cursor<'_┃> {
+ fn node(self) -> &SyntaxNode {
+ match self {
+ Cursor::Replace(node) | Cursor::Before(node) => node,
+ }
+ }
+}
+impl<'a> Cursor<'a> {
+ fn node(self) -> &SyntaxNode {
+ match self {
+ Cursor::Replace(node) | Cursor::Before(node) => node,
+ }
+ }
+}
+invert_if
Source: invert_if.rs
+This transforms if expressions of the form if !x {A} else {B}
into if x {B} else {A}
+This also works with !=
. This assist can only be applied with the cursor on if
.
fn main() {
+ if┃ !y { A } else { B }
+}
+fn main() {
+ if y { B } else { A }
+}
+line_to_block
Source: convert_comment_block.rs
+Converts comments between block and single-line form.
+ // Multi-line┃
+ // comment
+ /*
+ Multi-line
+ comment
+ */
+make_raw_string
Source: raw_string.rs
+Adds r#
to a plain string literal.
fn main() {
+ "Hello,┃ World!";
+}
+fn main() {
+ r#"Hello, World!"#;
+}
+make_usual_string
Source: raw_string.rs
+Turns a raw string into a plain string.
+fn main() {
+ r#"Hello,┃ "World!""#;
+}
+fn main() {
+ "Hello, \"World!\"";
+}
+merge_imports
Source: merge_imports.rs
+Merges two imports with a common prefix.
+use std::┃fmt::Formatter;
+use std::io;
+use std::{fmt::Formatter, io};
+merge_match_arms
Source: merge_match_arms.rs
+Merges the current match arm with the following if their bodies are identical.
+enum Action { Move { distance: u32 }, Stop }
+
+fn handle(action: Action) {
+ match action {
+ ┃Action::Move(..) => foo(),
+ Action::Stop => foo(),
+ }
+}
+enum Action { Move { distance: u32 }, Stop }
+
+fn handle(action: Action) {
+ match action {
+ Action::Move(..) | Action::Stop => foo(),
+ }
+}
+move_arm_cond_to_match_guard
Source: move_guard.rs
+Moves if expression from match arm body into a guard.
+enum Action { Move { distance: u32 }, Stop }
+
+fn handle(action: Action) {
+ match action {
+ Action::Move { distance } => ┃if distance > 10 { foo() },
+ _ => (),
+ }
+}
+enum Action { Move { distance: u32 }, Stop }
+
+fn handle(action: Action) {
+ match action {
+ Action::Move { distance } if distance > 10 => foo(),
+ _ => (),
+ }
+}
+move_bounds_to_where_clause
Source: move_bounds.rs
+Moves inline type bounds to a where clause.
+fn apply<T, U, ┃F: FnOnce(T) -> U>(f: F, x: T) -> U {
+ f(x)
+}
+fn apply<T, U, F>(f: F, x: T) -> U where F: FnOnce(T) -> U {
+ f(x)
+}
+move_const_to_impl
Source: move_const_to_impl.rs
+Move a local constant item in a method to impl's associated constant. All the references will be
+qualified with Self::
.
struct S;
+impl S {
+ fn foo() -> usize {
+ /// The answer.
+ const C┃: usize = 42;
+
+ C * C
+ }
+}
+struct S;
+impl S {
+ /// The answer.
+ const C: usize = 42;
+
+ fn foo() -> usize {
+ Self::C * Self::C
+ }
+}
+move_from_mod_rs
Source: move_from_mod_rs.rs
+Moves xxx/mod.rs to xxx.rs.
+//- /main.rs
+mod a;
+//- /a/mod.rs
+┃fn t() {}┃
+fn t() {}
+move_guard_to_arm_body
Source: move_guard.rs
+Moves match guard into match arm body.
+enum Action { Move { distance: u32 }, Stop }
+
+fn handle(action: Action) {
+ match action {
+ Action::Move { distance } ┃if distance > 10 => foo(),
+ _ => (),
+ }
+}
+enum Action { Move { distance: u32 }, Stop }
+
+fn handle(action: Action) {
+ match action {
+ Action::Move { distance } => if distance > 10 {
+ foo()
+ },
+ _ => (),
+ }
+}
+move_module_to_file
Source: move_module_to_file.rs
+Moves inline module's contents to a separate file.
+mod ┃foo {
+ fn t() {}
+}
+mod foo;
+move_to_mod_rs
Source: move_to_mod_rs.rs
+Moves xxx.rs to xxx/mod.rs.
+//- /main.rs
+mod a;
+//- /a.rs
+┃fn t() {}┃
+fn t() {}
+promote_local_to_const
Source: promote_local_to_const.rs
+Promotes a local variable to a const item changing its name to a SCREAMING_SNAKE_CASE
variant
+if the local uses no non-const expressions.
fn main() {
+ let foo┃ = true;
+
+ if foo {
+ println!("It's true");
+ } else {
+ println!("It's false");
+ }
+}
+fn main() {
+ const ┃FOO: bool = true;
+
+ if FOO {
+ println!("It's true");
+ } else {
+ println!("It's false");
+ }
+}
+pull_assignment_up
Source: pull_assignment_up.rs
+Extracts variable assignment to outside an if or match statement.
+fn main() {
+ let mut foo = 6;
+
+ if true {
+ ┃foo = 5;
+ } else {
+ foo = 4;
+ }
+}
+fn main() {
+ let mut foo = 6;
+
+ foo = if true {
+ 5
+ } else {
+ 4
+ };
+}
+qualify_method_call
Source: qualify_method_call.rs
+Replaces the method call with a qualified function call.
+struct Foo;
+impl Foo {
+ fn foo(&self) {}
+}
+fn main() {
+ let foo = Foo;
+ foo.fo┃o();
+}
+struct Foo;
+impl Foo {
+ fn foo(&self) {}
+}
+fn main() {
+ let foo = Foo;
+ Foo::foo(&foo);
+}
+qualify_path
Source: qualify_path.rs
+If the name is unresolved, provides all possible qualified paths for it.
+fn main() {
+ let map = HashMap┃::new();
+}
+fn main() {
+ let map = std::collections::HashMap::new();
+}
+reformat_number_literal
Source: number_representation.rs
+Adds or removes separators from integer literal.
+const _: i32 = 1012345┃;
+const _: i32 = 1_012_345;
+remove_dbg
Source: remove_dbg.rs
+Removes dbg!()
macro call.
fn main() {
+ let x = ┃dbg!(42 * dbg!(4 + 2));┃
+}
+fn main() {
+ let x = 42 * (4 + 2);
+}
+remove_hash
Source: raw_string.rs
+Removes a hash from a raw string literal.
+fn main() {
+ r#"Hello,┃ World!"#;
+}
+fn main() {
+ r"Hello, World!";
+}
+remove_mut
Source: remove_mut.rs
+Removes the mut
keyword.
impl Walrus {
+ fn feed(&mut┃ self, amount: u32) {}
+}
+impl Walrus {
+ fn feed(&self, amount: u32) {}
+}
+remove_parentheses
Source: remove_parentheses.rs
+Removes redundant parentheses.
+fn main() {
+ _ = ┃(2) + 2;
+}
+fn main() {
+ _ = 2 + 2;
+}
+remove_unused_imports
Source: remove_unused_imports.rs
+Removes any use statements in the current selection that are unused.
+struct X();
+mod foo {
+ use super::X┃;
+}
+struct X();
+mod foo {
+}
+remove_unused_param
Source: remove_unused_param.rs
+Removes unused function parameter.
+fn frobnicate(x: i32┃) {}
+
+fn main() {
+ frobnicate(92);
+}
+fn frobnicate() {}
+
+fn main() {
+ frobnicate();
+}
+reorder_fields
Source: reorder_fields.rs
+Reorder the fields of record literals and record patterns in the same order as in +the definition.
+struct Foo {foo: i32, bar: i32};
+const test: Foo = ┃Foo {bar: 0, foo: 1}
+struct Foo {foo: i32, bar: i32};
+const test: Foo = Foo {foo: 1, bar: 0}
+reorder_impl_items
Source: reorder_impl_items.rs
+Reorder the items of an impl Trait
. The items will be ordered
+in the same order as in the trait definition.
trait Foo {
+ type A;
+ const B: u8;
+ fn c();
+}
+
+struct Bar;
+┃impl Foo for Bar┃ {
+ const B: u8 = 17;
+ fn c() {}
+ type A = String;
+}
+trait Foo {
+ type A;
+ const B: u8;
+ fn c();
+}
+
+struct Bar;
+impl Foo for Bar {
+ type A = String;
+ const B: u8 = 17;
+ fn c() {}
+}
+replace_arith_with_checked
Source: replace_arith_op.rs
+Replaces arithmetic on integers with the checked_*
equivalent.
fn main() {
+ let x = 1 ┃+ 2;
+}
+fn main() {
+ let x = 1.checked_add(2);
+}
+replace_arith_with_saturating
Source: replace_arith_op.rs
+Replaces arithmetic on integers with the saturating_*
equivalent.
fn main() {
+ let x = 1 ┃+ 2;
+}
+fn main() {
+ let x = 1.saturating_add(2);
+}
+replace_arith_with_wrapping
Source: replace_arith_op.rs
+Replaces arithmetic on integers with the wrapping_*
equivalent.
fn main() {
+ let x = 1 ┃+ 2;
+}
+fn main() {
+ let x = 1.wrapping_add(2);
+}
+replace_char_with_string
Source: replace_string_with_char.rs
+Replace a char literal with a string literal.
+fn main() {
+ find('{┃');
+}
+fn main() {
+ find("{");
+}
+replace_derive_with_manual_impl
Source: replace_derive_with_manual_impl.rs
+Converts a derive
impl into a manual one.
#[derive(Deb┃ug, Display)]
+struct S;
+#[derive(Display)]
+struct S;
+
+impl Debug for S {
+ ┃fn fmt(&self, f: &mut Formatter) -> Result<()> {
+ f.debug_struct("S").finish()
+ }
+}
+replace_if_let_with_match
Source: replace_if_let_with_match.rs
+Replaces a if let
expression with a match
expression.
enum Action { Move { distance: u32 }, Stop }
+
+fn handle(action: Action) {
+ ┃if let Action::Move { distance } = action {
+ foo(distance)
+ } else {
+ bar()
+ }
+}
+enum Action { Move { distance: u32 }, Stop }
+
+fn handle(action: Action) {
+ match action {
+ Action::Move { distance } => foo(distance),
+ _ => bar(),
+ }
+}
+replace_is_some_with_if_let_some
Source: replace_is_method_with_if_let_method.rs
+Replace if x.is_some()
with if let Some(_tmp) = x
or if x.is_ok()
with if let Ok(_tmp) = x
.
fn main() {
+ let x = Some(1);
+ if x.is_som┃e() {}
+}
+fn main() {
+ let x = Some(1);
+ if let Some(${0:x}) = x {}
+}
+replace_let_with_if_let
Source: replace_let_with_if_let.rs
+Replaces let
with an if let
.
+fn main(action: Action) {
+ ┃let x = compute();
+}
+
+fn compute() -> Option<i32> { None }
+
+fn main(action: Action) {
+ if let Some(x) = compute() {
+ }
+}
+
+fn compute() -> Option<i32> { None }
+replace_match_with_if_let
Source: replace_if_let_with_match.rs
+Replaces a binary match
with a wildcard pattern and no guards with an if let
expression.
enum Action { Move { distance: u32 }, Stop }
+
+fn handle(action: Action) {
+ ┃match action {
+ Action::Move { distance } => foo(distance),
+ _ => bar(),
+ }
+}
+enum Action { Move { distance: u32 }, Stop }
+
+fn handle(action: Action) {
+ if let Action::Move { distance } = action {
+ foo(distance)
+ } else {
+ bar()
+ }
+}
+replace_named_generic_with_impl
Source: replace_named_generic_with_impl.rs
+Replaces named generic with an impl Trait
in function argument.
fn new<P┃: AsRef<Path>>(location: P) -> Self {}
+fn new(location: impl AsRef<Path>) -> Self {}
+replace_qualified_name_with_use
Source: replace_qualified_name_with_use.rs
+Adds a use statement for a given fully-qualified name.
+fn process(map: std::collections::┃HashMap<String, String>) {}
+use std::collections::HashMap;
+
+fn process(map: HashMap<String, String>) {}
+replace_string_with_char
Source: replace_string_with_char.rs
+Replace string literal with char literal.
+fn main() {
+ find("{┃");
+}
+fn main() {
+ find('{');
+}
+replace_try_expr_with_match
Source: replace_try_expr_with_match.rs
+Replaces a try
expression with a match
expression.
fn handle() {
+ let pat = Some(true)┃?;
+}
+fn handle() {
+ let pat = match Some(true) {
+ Some(it) => it,
+ None => return None,
+ };
+}
+replace_turbofish_with_explicit_type
Source: replace_turbofish_with_explicit_type.rs
+Converts ::<_>
to an explicit type assignment.
fn make<T>() -> T { ) }
+fn main() {
+ let a = make┃::<i32>();
+}
+fn make<T>() -> T { ) }
+fn main() {
+ let a: i32 = make();
+}
+replace_with_eager_method
Source: replace_method_eager_lazy.rs
+Replace unwrap_or_else
with unwrap_or
and ok_or_else
with ok_or
.
fn foo() {
+ let a = Some(1);
+ a.unwra┃p_or_else(|| 2);
+}
+fn foo() {
+ let a = Some(1);
+ a.unwrap_or(2);
+}
+replace_with_lazy_method
Source: replace_method_eager_lazy.rs
+Replace unwrap_or
with unwrap_or_else
and ok_or
with ok_or_else
.
fn foo() {
+ let a = Some(1);
+ a.unwra┃p_or(2);
+}
+fn foo() {
+ let a = Some(1);
+ a.unwrap_or_else(|| 2);
+}
+sort_items
Source: sort_items.rs
+Sorts item members alphabetically: fields, enum variants and methods.
+struct ┃Foo┃ { second: u32, first: String }
+struct Foo { first: String, second: u32 }
+trait ┃Bar┃ {
+ fn second(&self) -> u32;
+ fn first(&self) -> String;
+}
+trait Bar {
+ fn first(&self) -> String;
+ fn second(&self) -> u32;
+}
+struct Baz;
+impl ┃Baz┃ {
+ fn second(&self) -> u32;
+ fn first(&self) -> String;
+}
+struct Baz;
+impl Baz {
+ fn first(&self) -> String;
+ fn second(&self) -> u32;
+}
+There is a difference between sorting enum variants:
+enum ┃Animal┃ {
+ Dog(String, f64),
+ Cat { weight: f64, name: String },
+}
+enum Animal {
+ Cat { weight: f64, name: String },
+ Dog(String, f64),
+}
+and sorting a single enum struct variant:
+enum Animal {
+ Dog(String, f64),
+ Cat ┃{ weight: f64, name: String }┃,
+}
+enum Animal {
+ Dog(String, f64),
+ Cat { name: String, weight: f64 },
+}
+split_import
Source: split_import.rs
+Wraps the tail of import into braces.
+use std::┃collections::HashMap;
+use std::{collections::HashMap};
+toggle_ignore
Source: toggle_ignore.rs
+Adds #[ignore]
attribute to the test.
┃#[test]
+fn arithmetics {
+ assert_eq!(2 + 2, 5);
+}
+#[test]
+#[ignore]
+fn arithmetics {
+ assert_eq!(2 + 2, 5);
+}
+unmerge_match_arm
Source: unmerge_match_arm.rs
+Splits the current match with a |
pattern into two arms with identical bodies.
enum Action { Move { distance: u32 }, Stop }
+
+fn handle(action: Action) {
+ match action {
+ Action::Move(..) ┃| Action::Stop => foo(),
+ }
+}
+enum Action { Move { distance: u32 }, Stop }
+
+fn handle(action: Action) {
+ match action {
+ Action::Move(..) => foo(),
+ Action::Stop => foo(),
+ }
+}
+unmerge_use
Source: unmerge_use.rs
+Extracts single use item from use list.
+use std::fmt::{Debug, Display┃};
+use std::fmt::{Debug};
+use std::fmt::Display;
+unnecessary_async
Source: unnecessary_async.rs
+Removes the async
mark from functions which have no .await
in their body.
+Looks for calls to the functions and removes the .await
on the call site.
pub async f┃n foo() {}
+pub async fn bar() { foo().await }
+pub fn foo() {}
+pub async fn bar() { foo() }
+unqualify_method_call
Source: unqualify_method_call.rs
+Transforms universal function call syntax into a method call.
+fn main() {
+ std::ops::Add::add┃(1, 2);
+}
+use std::ops::Add;
+
+fn main() {
+ 1.add(2);
+}
+unwrap_block
Source: unwrap_block.rs
+This assist removes if...else, for, while and loop control statements to just keep the body.
+fn foo() {
+ if true {┃
+ println!("foo");
+ }
+}
+fn foo() {
+ println!("foo");
+}
+unwrap_result_return_type
Source: unwrap_result_return_type.rs
+Unwrap the function's return type.
+fn foo() -> Result<i32>┃ { Ok(42i32) }
+fn foo() -> i32 { 42i32 }
+unwrap_tuple
Source: unwrap_tuple.rs
+Unwrap the tuple to different variables.
+fn main() {
+ ┃let (foo, bar) = ("Foo", "Bar");
+}
+fn main() {
+ let foo = "Foo";
+ let bar = "Bar";
+}
+wrap_return_type_in_result
Source: wrap_return_type_in_result.rs
+Wrap the function's return type into Result.
+fn foo() -> i32┃ { 42i32 }
+fn foo() -> Result<i32, ${0:_}> { Ok(42i32) }
+
+ Source: +config.rs
+The Installation section contains details on
+configuration for some of the editors. In general rust-analyzer
is
+configured via LSP messages, which means that it’s up to the editor to
+decide on the exact format and location of configuration files.
Some clients, such as VS Code or COC plugin in
+Vim provide rust-analyzer
specific configuration
+UIs. Others may require you to know a bit more about the interaction
+with rust-analyzer
.
For the later category, it might help to know that the initial
+configuration is specified as a value of the initializationOptions
+field of the InitializeParams
message, in the LSP
+protocol.
+The spec says that the field type is any?
, but rust-analyzer
is
+looking for a JSON object that is constructed using settings from the
+list below. Name of the setting, ignoring the rust-analyzer.
prefix,
+is used as a path, and value of the setting becomes the JSON property
+value.
For example, a very common configuration is to enable proc-macro +support, can be achieved by sending this JSON:
+{
+ "cargo": {
+ "buildScripts": {
+ "enable": true,
+ },
+ },
+ "procMacro": {
+ "enable": true,
+ }
+}
+
+Please consult your editor’s documentation to learn more about how to +configure LSP +servers.
+To verify which configuration is actually used by rust-analyzer
, set
+RA_LOG
environment variable to rust_analyzer=info
and look for
+config-related messages. Logs should show both the JSON that
+rust-analyzer
sees as well as the updated config.
This is the list of config options rust-analyzer
supports:
rust-analyzer.assist.emitMustUse (default: false)
+Whether to insert #[must_use] when generating as_
methods
+for enum variants.
rust-analyzer.assist.expressionFillDefault (default: "todo")
+Placeholder expression to use for missing expressions in assists.
+rust-analyzer.cachePriming.enable (default: true)
+Warm up caches on project load.
+rust-analyzer.cachePriming.numThreads (default: 0)
+How many worker threads to handle priming caches. The default 0
means to pick automatically.
rust-analyzer.cargo.autoreload (default: true)
+Automatically refresh project info via cargo metadata
on
+Cargo.toml
or .cargo/config.toml
changes.
rust-analyzer.cargo.buildScripts.enable (default: true)
+Run build scripts (build.rs
) for more precise code analysis.
rust-analyzer.cargo.buildScripts.invocationLocation (default: "workspace")
+Specifies the working directory for running build scripts.
+#rust-analyzer.cargo.buildScripts.invocationStrategy#
set to once
.#rust-analyzer.cargo.buildScripts.overrideCommand#
+is set.rust-analyzer.cargo.buildScripts.invocationStrategy (default: "per_workspace")
+Specifies the invocation strategy to use when running the build scripts command.
+If per_workspace
is set, the command will be executed for each workspace.
+If once
is set, the command will be executed once.
+This config only has an effect when #rust-analyzer.cargo.buildScripts.overrideCommand#
+is set.
rust-analyzer.cargo.buildScripts.overrideCommand (default: null)
+Override the command rust-analyzer uses to run build scripts and
+build procedural macros. The command is required to output json
+and should therefore include --message-format=json
or a similar
+option.
If there are multiple linked projects/workspaces, this command is invoked for
+each of them, with the working directory being the workspace root
+(i.e., the folder containing the Cargo.toml
). This can be overwritten
+by changing #rust-analyzer.cargo.buildScripts.invocationStrategy#
and
+#rust-analyzer.cargo.buildScripts.invocationLocation#
.
By default, a cargo invocation will be constructed for the configured +targets and features, with the following base command line:
+cargo check --quiet --workspace --message-format=json --all-targets
+
+.
+rust-analyzer.cargo.buildScripts.useRustcWrapper (default: true)
+Use RUSTC_WRAPPER=rust-analyzer
when running build scripts to
+avoid checking unnecessary things.
rust-analyzer.cargo.cfgs (default: {})
+List of cfg options to enable with the given values.
+rust-analyzer.cargo.extraArgs (default: [])
+Extra arguments that are passed to every cargo invocation.
+rust-analyzer.cargo.extraEnv (default: {})
+Extra environment variables that will be set when running cargo, rustc +or other commands within the workspace. Useful for setting RUSTFLAGS.
+rust-analyzer.cargo.features (default: [])
+List of features to activate.
+Set this to "all"
to pass --all-features
to cargo.
rust-analyzer.cargo.noDefaultFeatures (default: false)
+Whether to pass --no-default-features
to cargo.
rust-analyzer.cargo.sysroot (default: "discover")
+Relative path to the sysroot, or "discover" to try to automatically find it via +"rustc --print sysroot".
+Unsetting this disables sysroot loading.
+This option does not take effect until rust-analyzer is restarted.
+rust-analyzer.cargo.sysrootSrc (default: null)
+Relative path to the sysroot library sources. If left unset, this will default to
+{cargo.sysroot}/lib/rustlib/src/rust/library
.
This option does not take effect until rust-analyzer is restarted.
+rust-analyzer.cargo.target (default: null)
+Compilation target override (target triple).
+rust-analyzer.cargo.unsetTest (default: ["core"])
+Unsets the implicit #[cfg(test)]
for the specified crates.
rust-analyzer.checkOnSave (default: true)
+Run the check command for diagnostics on save.
+rust-analyzer.check.allTargets (default: true)
+Check all targets and tests (--all-targets
).
rust-analyzer.check.command (default: "check")
+Cargo command to use for cargo check
.
rust-analyzer.check.extraArgs (default: [])
+Extra arguments for cargo check
.
rust-analyzer.check.extraEnv (default: {})
+Extra environment variables that will be set when running cargo check
.
+Extends #rust-analyzer.cargo.extraEnv#
.
rust-analyzer.check.features (default: null)
+List of features to activate. Defaults to
+#rust-analyzer.cargo.features#
.
Set to "all"
to pass --all-features
to Cargo.
rust-analyzer.check.ignore (default: [])
+List of cargo check
(or other command specified in check.command
) diagnostics to ignore.
For example for cargo check
: dead_code
, unused_imports
, unused_variables
,...
rust-analyzer.check.invocationLocation (default: "workspace")
+Specifies the working directory for running checks.
+#rust-analyzer.cargo.check.invocationStrategy#
is set to once
.#rust-analyzer.cargo.check.overrideCommand#
+is set.rust-analyzer.check.invocationStrategy (default: "per_workspace")
+Specifies the invocation strategy to use when running the check command.
+If per_workspace
is set, the command will be executed for each workspace.
+If once
is set, the command will be executed once.
+This config only has an effect when #rust-analyzer.cargo.check.overrideCommand#
+is set.
rust-analyzer.check.noDefaultFeatures (default: null)
+Whether to pass --no-default-features
to Cargo. Defaults to
+#rust-analyzer.cargo.noDefaultFeatures#
.
rust-analyzer.check.overrideCommand (default: null)
+Override the command rust-analyzer uses instead of cargo check
for
+diagnostics on save. The command is required to output json and
+should therefore include --message-format=json
or a similar option
+(if your client supports the colorDiagnosticOutput
experimental
+capability, you can use --message-format=json-diagnostic-rendered-ansi
).
If you're changing this because you're using some tool wrapping
+Cargo, you might also want to change
+#rust-analyzer.cargo.buildScripts.overrideCommand#
.
If there are multiple linked projects/workspaces, this command is invoked for
+each of them, with the working directory being the workspace root
+(i.e., the folder containing the Cargo.toml
). This can be overwritten
+by changing #rust-analyzer.cargo.check.invocationStrategy#
and
+#rust-analyzer.cargo.check.invocationLocation#
.
An example command would be:
+cargo check --workspace --message-format=json --all-targets
+
+.
+rust-analyzer.check.targets (default: null)
+Check for specific targets. Defaults to #rust-analyzer.cargo.target#
if empty.
Can be a single target, e.g. "x86_64-unknown-linux-gnu"
or a list of targets, e.g.
+["aarch64-apple-darwin", "x86_64-apple-darwin"]
.
Aliased as "checkOnSave.targets"
.
rust-analyzer.completion.autoimport.enable (default: true)
+Toggles the additional completions that automatically add imports when completed.
+Note that your client must specify the additionalTextEdits
LSP client capability to truly have this feature enabled.
rust-analyzer.completion.autoself.enable (default: true)
+Toggles the additional completions that automatically show method calls and field accesses
+with self
prefixed to them when inside a method.
rust-analyzer.completion.callable.snippets (default: "fill_arguments")
+Whether to add parenthesis and argument snippets when completing function.
+rust-analyzer.completion.fullFunctionSignatures.enable (default: false)
+Whether to show full function/method signatures in completion docs.
+rust-analyzer.completion.limit (default: null)
+Maximum number of completions to return. If None
, the limit is infinite.
rust-analyzer.completion.postfix.enable (default: true)
+Whether to show postfix snippets like dbg
, if
, not
, etc.
rust-analyzer.completion.privateEditable.enable (default: false)
+Enables completions of private items and fields that are defined in the current workspace even if they are not visible at the current position.
+rust-analyzer.completion.snippets.custom
+Default:
+ "Arc::new": {
+ "postfix": "arc",
+ "body": "Arc::new(${receiver})",
+ "requires": "std::sync::Arc",
+ "description": "Put the expression into an `Arc`",
+ "scope": "expr"
+ },
+ "Rc::new": {
+ "postfix": "rc",
+ "body": "Rc::new(${receiver})",
+ "requires": "std::rc::Rc",
+ "description": "Put the expression into an `Rc`",
+ "scope": "expr"
+ },
+ "Box::pin": {
+ "postfix": "pinbox",
+ "body": "Box::pin(${receiver})",
+ "requires": "std::boxed::Box",
+ "description": "Put the expression into a pinned `Box`",
+ "scope": "expr"
+ },
+ "Ok": {
+ "postfix": "ok",
+ "body": "Ok(${receiver})",
+ "description": "Wrap the expression in a `Result::Ok`",
+ "scope": "expr"
+ },
+ "Err": {
+ "postfix": "err",
+ "body": "Err(${receiver})",
+ "description": "Wrap the expression in a `Result::Err`",
+ "scope": "expr"
+ },
+ "Some": {
+ "postfix": "some",
+ "body": "Some(${receiver})",
+ "description": "Wrap the expression in an `Option::Some`",
+ "scope": "expr"
+ }
+ }
+
+
+Custom completion snippets.
+rust-analyzer.diagnostics.disabled (default: [])
+List of rust-analyzer diagnostics to disable.
+rust-analyzer.diagnostics.enable (default: true)
+Whether to show native rust-analyzer diagnostics.
+rust-analyzer.diagnostics.experimental.enable (default: false)
+Whether to show experimental rust-analyzer diagnostics that might +have more false positives than usual.
+rust-analyzer.diagnostics.remapPrefix (default: {})
+Map of prefixes to be substituted when parsing diagnostic file paths.
+This should be the reverse mapping of what is passed to rustc
as --remap-path-prefix
.
rust-analyzer.diagnostics.warningsAsHint (default: [])
+List of warnings that should be displayed with hint severity.
+The warnings will be indicated by faded text or three dots in code
+and will not show up in the Problems Panel
.
rust-analyzer.diagnostics.warningsAsInfo (default: [])
+List of warnings that should be displayed with info severity.
+The warnings will be indicated by a blue squiggly underline in code
+and a blue icon in the Problems Panel
.
rust-analyzer.files.excludeDirs (default: [])
+These directories will be ignored by rust-analyzer. They are
+relative to the workspace root, and globs are not supported. You may
+also need to add the folders to Code's files.watcherExclude
.
rust-analyzer.files.watcher (default: "client")
+Controls file watching implementation.
+rust-analyzer.highlightRelated.breakPoints.enable (default: true)
+Enables highlighting of related references while the cursor is on break
, loop
, while
, or for
keywords.
rust-analyzer.highlightRelated.closureCaptures.enable (default: true)
+Enables highlighting of all captures of a closure while the cursor is on the |
or move keyword of a closure.
rust-analyzer.highlightRelated.exitPoints.enable (default: true)
+Enables highlighting of all exit points while the cursor is on any return
, ?
, fn
, or return type arrow (->
).
rust-analyzer.highlightRelated.references.enable (default: true)
+Enables highlighting of related references while the cursor is on any identifier.
+rust-analyzer.highlightRelated.yieldPoints.enable (default: true)
+Enables highlighting of all break points for a loop or block context while the cursor is on any async
or await
keywords.
rust-analyzer.hover.actions.debug.enable (default: true)
+Whether to show Debug
action. Only applies when
+#rust-analyzer.hover.actions.enable#
is set.
rust-analyzer.hover.actions.enable (default: true)
+Whether to show HoverActions in Rust files.
+rust-analyzer.hover.actions.gotoTypeDef.enable (default: true)
+Whether to show Go to Type Definition
action. Only applies when
+#rust-analyzer.hover.actions.enable#
is set.
rust-analyzer.hover.actions.implementations.enable (default: true)
+Whether to show Implementations
action. Only applies when
+#rust-analyzer.hover.actions.enable#
is set.
rust-analyzer.hover.actions.references.enable (default: false)
+Whether to show References
action. Only applies when
+#rust-analyzer.hover.actions.enable#
is set.
rust-analyzer.hover.actions.run.enable (default: true)
+Whether to show Run
action. Only applies when
+#rust-analyzer.hover.actions.enable#
is set.
rust-analyzer.hover.documentation.enable (default: true)
+Whether to show documentation on hover.
+rust-analyzer.hover.documentation.keywords.enable (default: true)
+Whether to show keyword hover popups. Only applies when
+#rust-analyzer.hover.documentation.enable#
is set.
rust-analyzer.hover.links.enable (default: true)
+Use markdown syntax for links on hover.
+rust-analyzer.hover.memoryLayout.alignment (default: "hexadecimal")
+How to render the align information in a memory layout hover.
+rust-analyzer.hover.memoryLayout.enable (default: true)
+Whether to show memory layout data on hover.
+rust-analyzer.hover.memoryLayout.niches (default: false)
+How to render the niche information in a memory layout hover.
+rust-analyzer.hover.memoryLayout.offset (default: "hexadecimal")
+How to render the offset information in a memory layout hover.
+rust-analyzer.hover.memoryLayout.size (default: "both")
+How to render the size information in a memory layout hover.
+rust-analyzer.imports.granularity.enforce (default: false)
+Whether to enforce the import granularity setting for all files. If set to false rust-analyzer will try to keep import styles consistent per file.
+rust-analyzer.imports.granularity.group (default: "crate")
+How imports should be grouped into use statements.
+rust-analyzer.imports.group.enable (default: true)
+Group inserted imports by the following order. Groups are separated by newlines.
+rust-analyzer.imports.merge.glob (default: true)
+Whether to allow import insertion to merge new imports into single path glob imports like use std::fmt::*;
.
rust-analyzer.imports.prefer.no.std (default: false)
+Prefer to unconditionally use imports of the core and alloc crate, over the std crate.
+rust-analyzer.imports.prefix (default: "plain")
+The path structure for newly inserted paths to use.
+rust-analyzer.inlayHints.bindingModeHints.enable (default: false)
+Whether to show inlay type hints for binding modes.
+rust-analyzer.inlayHints.chainingHints.enable (default: true)
+Whether to show inlay type hints for method chains.
+rust-analyzer.inlayHints.closingBraceHints.enable (default: true)
+Whether to show inlay hints after a closing }
to indicate what item it belongs to.
rust-analyzer.inlayHints.closingBraceHints.minLines (default: 25)
+Minimum number of lines required before the }
until the hint is shown (set to 0 or 1
+to always show them).
rust-analyzer.inlayHints.closureCaptureHints.enable (default: false)
+Whether to show inlay hints for closure captures.
+rust-analyzer.inlayHints.closureReturnTypeHints.enable (default: "never")
+Whether to show inlay type hints for return types of closures.
+rust-analyzer.inlayHints.closureStyle (default: "impl_fn")
+Closure notation in type and chaining inlay hints.
+rust-analyzer.inlayHints.discriminantHints.enable (default: "never")
+Whether to show enum variant discriminant hints.
+rust-analyzer.inlayHints.expressionAdjustmentHints.enable (default: "never")
+Whether to show inlay hints for type adjustments.
+rust-analyzer.inlayHints.expressionAdjustmentHints.hideOutsideUnsafe (default: false)
+Whether to hide inlay hints for type adjustments outside of unsafe
blocks.
rust-analyzer.inlayHints.expressionAdjustmentHints.mode (default: "prefix")
+Whether to show inlay hints as postfix ops (.*
instead of *
, etc).
rust-analyzer.inlayHints.lifetimeElisionHints.enable (default: "never")
+Whether to show inlay type hints for elided lifetimes in function signatures.
+rust-analyzer.inlayHints.lifetimeElisionHints.useParameterNames (default: false)
+Whether to prefer using parameter names as the name for elided lifetime hints if possible.
+rust-analyzer.inlayHints.maxLength (default: 25)
+Maximum length for inlay hints. Set to null to have an unlimited length.
+rust-analyzer.inlayHints.parameterHints.enable (default: true)
+Whether to show function parameter name inlay hints at the call +site.
+rust-analyzer.inlayHints.reborrowHints.enable (default: "never")
+Whether to show inlay hints for compiler inserted reborrows. +This setting is deprecated in favor of #rust-analyzer.inlayHints.expressionAdjustmentHints.enable#.
+rust-analyzer.inlayHints.renderColons (default: true)
+Whether to render leading colons for type hints, and trailing colons for parameter hints.
+rust-analyzer.inlayHints.typeHints.enable (default: true)
+Whether to show inlay type hints for variables.
+rust-analyzer.inlayHints.typeHints.hideClosureInitialization (default: false)
+Whether to hide inlay type hints for let
statements that initialize to a closure.
+Only applies to closures with blocks, same as #rust-analyzer.inlayHints.closureReturnTypeHints.enable#
.
rust-analyzer.inlayHints.typeHints.hideNamedConstructor (default: false)
+Whether to hide inlay type hints for constructors.
+rust-analyzer.interpret.tests (default: false)
+Enables the experimental support for interpreting tests.
+rust-analyzer.joinLines.joinAssignments (default: true)
+Join lines merges consecutive declaration and initialization of an assignment.
+rust-analyzer.joinLines.joinElseIf (default: true)
+Join lines inserts else between consecutive ifs.
+rust-analyzer.joinLines.removeTrailingComma (default: true)
+Join lines removes trailing commas.
+rust-analyzer.joinLines.unwrapTrivialBlock (default: true)
+Join lines unwraps trivial blocks.
+rust-analyzer.lens.debug.enable (default: true)
+Whether to show Debug
lens. Only applies when
+#rust-analyzer.lens.enable#
is set.
rust-analyzer.lens.enable (default: true)
+Whether to show CodeLens in Rust files.
+rust-analyzer.lens.forceCustomCommands (default: true)
+Internal config: use custom client-side commands even when the +client doesn't set the corresponding capability.
+rust-analyzer.lens.implementations.enable (default: true)
+Whether to show Implementations
lens. Only applies when
+#rust-analyzer.lens.enable#
is set.
rust-analyzer.lens.location (default: "above_name")
+Where to render annotations.
+rust-analyzer.lens.references.adt.enable (default: false)
+Whether to show References
lens for Struct, Enum, and Union.
+Only applies when #rust-analyzer.lens.enable#
is set.
rust-analyzer.lens.references.enumVariant.enable (default: false)
+Whether to show References
lens for Enum Variants.
+Only applies when #rust-analyzer.lens.enable#
is set.
rust-analyzer.lens.references.method.enable (default: false)
+Whether to show Method References
lens. Only applies when
+#rust-analyzer.lens.enable#
is set.
rust-analyzer.lens.references.trait.enable (default: false)
+Whether to show References
lens for Trait.
+Only applies when #rust-analyzer.lens.enable#
is set.
rust-analyzer.lens.run.enable (default: true)
+Whether to show Run
lens. Only applies when
+#rust-analyzer.lens.enable#
is set.
rust-analyzer.linkedProjects (default: [])
+Disable project auto-discovery in favor of explicitly specified set +of projects.
+Elements must be paths pointing to Cargo.toml
,
+rust-project.json
, or JSON objects in rust-project.json
format.
rust-analyzer.lru.capacity (default: null)
+Number of syntax trees rust-analyzer keeps in memory. Defaults to 128.
+rust-analyzer.lru.query.capacities (default: {})
+Sets the LRU capacity of the specified queries.
+rust-analyzer.notifications.cargoTomlNotFound (default: true)
+Whether to show can't find Cargo.toml
error message.
rust-analyzer.numThreads (default: null)
+How many worker threads in the main loop. The default null
means to pick automatically.
rust-analyzer.procMacro.attributes.enable (default: true)
+Expand attribute macros. Requires #rust-analyzer.procMacro.enable#
to be set.
rust-analyzer.procMacro.enable (default: true)
+Enable support for procedural macros, implies #rust-analyzer.cargo.buildScripts.enable#
.
rust-analyzer.procMacro.ignored (default: {})
+These proc-macros will be ignored when trying to expand them.
+This config takes a map of crate names with the exported proc-macro names to ignore as values.
+rust-analyzer.procMacro.server (default: null)
+Internal config, path to proc-macro server executable.
+rust-analyzer.references.excludeImports (default: false)
+Exclude imports from find-all-references.
+rust-analyzer.runnables.command (default: null)
+Command to be executed instead of 'cargo' for runnables.
+rust-analyzer.runnables.extraArgs (default: [])
+Additional arguments to be passed to cargo for runnables such as
+tests or binaries. For example, it may be --release
.
rust-analyzer.rust.analyzerTargetDir (default: null)
+Optional path to a rust-analyzer specific target directory.
+This prevents rust-analyzer's cargo check
from locking the Cargo.lock
+at the expense of duplicating build artifacts.
Set to true
to use a subdirectory of the existing target directory or
+set to a path relative to the workspace to use that path.
rust-analyzer.rustc.source (default: null)
+Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private
+projects, or "discover" to try to automatically find it if the rustc-dev
component
+is installed.
Any project which uses rust-analyzer with the rustcPrivate
+crates must set [package.metadata.rust-analyzer] rustc_private=true
to use it.
This option does not take effect until rust-analyzer is restarted.
+rust-analyzer.rustfmt.extraArgs (default: [])
+Additional arguments to rustfmt
.
rust-analyzer.rustfmt.overrideCommand (default: null)
+Advanced option, fully override the command rust-analyzer uses for
+formatting. This should be the equivalent of rustfmt
here, and
+not that of cargo fmt
. The file contents will be passed on the
+standard input and the formatted result will be read from the
+standard output.
rust-analyzer.rustfmt.rangeFormatting.enable (default: false)
+Enables the use of rustfmt's unstable range formatting command for the
+textDocument/rangeFormatting
request. The rustfmt option is unstable and only
+available on a nightly build.
rust-analyzer.semanticHighlighting.doc.comment.inject.enable (default: true)
+Inject additional highlighting into doc comments.
+When enabled, rust-analyzer will highlight rust source in doc comments as well as intra +doc links.
+rust-analyzer.semanticHighlighting.nonStandardTokens (default: true)
+Whether the server is allowed to emit non-standard tokens and modifiers.
+rust-analyzer.semanticHighlighting.operator.enable (default: true)
+Use semantic tokens for operators.
+When disabled, rust-analyzer will emit semantic tokens only for operator tokens when +they are tagged with modifiers.
+rust-analyzer.semanticHighlighting.operator.specialization.enable (default: false)
+Use specialized semantic tokens for operators.
+When enabled, rust-analyzer will emit special token types for operator tokens instead
+of the generic operator
token type.
rust-analyzer.semanticHighlighting.punctuation.enable (default: false)
+Use semantic tokens for punctuation.
+When disabled, rust-analyzer will emit semantic tokens only for punctuation tokens when +they are tagged with modifiers or have a special role.
+rust-analyzer.semanticHighlighting.punctuation.separate.macro.bang (default: false)
+When enabled, rust-analyzer will emit a punctuation semantic token for the !
of macro
+calls.
rust-analyzer.semanticHighlighting.punctuation.specialization.enable (default: false)
+Use specialized semantic tokens for punctuation.
+When enabled, rust-analyzer will emit special token types for punctuation tokens instead
+of the generic punctuation
token type.
rust-analyzer.semanticHighlighting.strings.enable (default: true)
+Use semantic tokens for strings.
+In some editors (e.g. vscode) semantic tokens override other highlighting grammars. +By disabling semantic tokens for strings, other grammars can be used to highlight +their contents.
+rust-analyzer.signatureInfo.detail (default: "full")
+Show full signature of the callable. Only shows parameters if disabled.
+rust-analyzer.signatureInfo.documentation.enable (default: true)
+Show documentation.
+rust-analyzer.typing.autoClosingAngleBrackets.enable (default: false)
+Whether to insert closing angle brackets when typing an opening angle bracket of a generic argument list.
+rust-analyzer.workspace.symbol.search.kind (default: "only_types")
+Workspace symbol search kind.
+rust-analyzer.workspace.symbol.search.limit (default: 128)
+Limits the number of items returned from a workspace symbol search (Defaults to 128). +Some clients like vs-code issue new searches on result filtering and don't require all results to be returned in the initial search. +Other clients requires all results upfront and might require a higher limit.
+rust-analyzer.workspace.symbol.search.scope (default: "workspace")
+Workspace symbol search scope.
+ +While most errors and warnings provided by rust-analyzer come from the
+cargo check
integration, there’s a growing number of diagnostics
+implemented using rust-analyzer’s own analysis. Some of these
+diagnostics don’t respect #[allow]
or \#[deny]
attributes yet, but
+can be turned off using the rust-analyzer.diagnostics.enable
,
+rust-analyzer.diagnostics.experimental.enable
or
+rust-analyzer.diagnostics.disabled
settings.
To run cargo clippy
instead of cargo check
, you can set
+"rust-analyzer.check.command": "clippy"
.
Source: break_outside_of_loop.rs
+This diagnostic is triggered if the break
keyword is used outside of a loop.
Source: expected_function.rs
+This diagnostic is triggered if a call is made on something that is not callable.
+Source: inactive_code.rs
+This diagnostic is shown for code with inactive #[cfg]
attributes.
Source: incoherent_impl.rs
+This diagnostic is triggered if the targe type of an impl is from a foreign crate.
+Source: incorrect_case.rs
+This diagnostic is triggered if an item name doesn't follow Rust naming convention.
+Source: invalid_derive_target.rs
+This diagnostic is shown when the derive attribute is used on an item other than a struct
,
+enum
or union
.
Source: macro_error.rs
+This diagnostic is shown for macro expansion errors.
+Source: macro_error.rs
+This diagnostic is shown for macro expansion errors.
+Source: malformed_derive.rs
+This diagnostic is shown when the derive attribute has invalid input.
+Source: mismatched_arg_count.rs
+This diagnostic is triggered if a function is invoked with an incorrect amount of arguments.
+Source: mismatched_arg_count.rs
+This diagnostic is triggered if a function is invoked with an incorrect amount of arguments.
+Source: missing_fields.rs
+This diagnostic is triggered if record lacks some fields that exist in the corresponding structure.
+Example:
+struct A { a: u8, b: u8 }
+
+let a = A { a: 10 };
+Source: missing_match_arms.rs
+This diagnostic is triggered if match
block is missing one or more match arms.
Source: missing_unsafe.rs
+This diagnostic is triggered if an operation marked as unsafe
is used outside of an unsafe
function or block.
Source: moved_out_of_ref.rs
+This diagnostic is triggered on moving non copy things out of references.
+Source: mutability_errors.rs
+This diagnostic is triggered on mutating an immutable variable.
+Source: no_such_field.rs
+This diagnostic is triggered if created structure does not have field provided in record.
+Source: private_assoc_item.rs
+This diagnostic is triggered if the referenced associated item is not visible from the current +module.
+Source: private_field.rs
+This diagnostic is triggered if the accessed field is not visible from the current module.
+Source: replace_filter_map_next_with_find_map.rs
+This diagnostic is triggered when .filter_map(..).next()
is used, rather than the more concise .find_map(..)
.
Source: type_mismatch.rs
+This diagnostic is triggered when the type of an expression or pattern does not match +the expected type.
+Source: typed_hole.rs
+This diagnostic is triggered when an underscore expression is used in an invalid position.
+Source: undeclared_label.rs
+Source: unimplemented_builtin_macro.rs
+This diagnostic is shown for builtin macros which are not yet implemented by rust-analyzer
+Source: unlinked_file.rs
+This diagnostic is shown for files that are not included in any crate, or files that are part of +crates rust-analyzer failed to discover. The file will not have IDE features available.
+Source: useless_braces.rs
+Diagnostic for unnecessary braces in use
items.
Source: unreachable_label.rs
+Source: unresolved_extern_crate.rs
+This diagnostic is triggered if rust-analyzer is unable to discover referred extern crate.
+Source: unresolved_field.rs
+This diagnostic is triggered if a field does not exist on a given type.
+Source: unresolved_import.rs
+This diagnostic is triggered if rust-analyzer is unable to resolve a path in
+a use
declaration.
Source: unresolved_macro_call.rs
+This diagnostic is triggered if rust-analyzer is unable to resolve the path +to a macro in a macro invocation.
+Source: unresolved_method.rs
+This diagnostic is triggered if a method does not exist on a given type.
+Source: unresolved_module.rs
+This diagnostic is triggered if rust-analyzer is unable to discover referred module.
+Source: unresolved_proc_macro.rs
+This diagnostic is shown when a procedural macro can not be found. This usually means that +procedural macro support is simply disabled (and hence is only a weak hint instead of an error), +but can also indicate project setup problems.
+If you are seeing a lot of "proc macro not expanded" warnings, you can add this option to the
+rust-analyzer.diagnostics.disabled
list to prevent them from showing. Alternatively you can
+enable support for procedural macros (see rust-analyzer.procMacro.attributes.enable
).
Source: mutability_errors.rs
+This diagnostic is triggered when a mutable variable isn't actually mutated.
+Source: unused_variables.rs
+This diagnostic is triggered when a local variable is not used.
+ +It is possible to change the foreground/background color and font
+family/size of inlay hints. Just add this to your settings.json
:
{
+ "editor.inlayHints.fontFamily": "Courier New",
+ "editor.inlayHints.fontSize": 11,
+
+ "workbench.colorCustomizations": {
+ // Name of the theme you are currently using
+ "[Default Dark+]": {
+ "editorInlayHint.foreground": "#868686f0",
+ "editorInlayHint.background": "#3d3d3d48",
+
+ // Overrides for specific kinds of inlay hints
+ "editorInlayHint.typeForeground": "#fdb6fdf0",
+ "editorInlayHint.parameterForeground": "#fdb6fdf0",
+ }
+ }
+}
+
+You can customize the look of different semantic elements in the source
+code. For example, mutable bindings are underlined by default and you
+can override this behavior by adding the following section to your
+settings.json
:
{
+ "editor.semanticTokenColorCustomizations": {
+ "rules": {
+ "*.mutable": {
+ "fontStyle": "", // underline is the default
+ },
+ }
+ },
+}
+
+Most themes doesn’t support styling unsafe operations differently yet.
+You can fix this by adding overrides for the rules operator.unsafe
,
+function.unsafe
, and method.unsafe
:
{
+ "editor.semanticTokenColorCustomizations": {
+ "rules": {
+ "operator.unsafe": "#ff6600",
+ "function.unsafe": "#ff6600",
+ "method.unsafe": "#ff6600"
+ }
+ },
+}
+
+In addition to the top-level rules you can specify overrides for +specific themes. For example, if you wanted to use a darker text color +on a specific light theme, you might write:
+{
+ "editor.semanticTokenColorCustomizations": {
+ "rules": {
+ "operator.unsafe": "#ff6600"
+ },
+ "[Ayu Light]": {
+ "rules": {
+ "operator.unsafe": "#572300"
+ }
+ }
+ },
+}
+
+Make sure you include the brackets around the theme name. For example,
+use "[Ayu Light]"
to customize the theme Ayu Light.
when
clause context for keybindings.You may use inRustProject
context to configure keybindings for rust
+projects only. For example:
{
+ "key": "ctrl+alt+d",
+ "command": "rust-analyzer.openDocs",
+ "when": "inRustProject"
+}
+
+More about when
clause contexts
+here.
You can use "rust-analyzer.runnables.extraEnv" setting to define +runnable environment-specific substitution variables. The simplest way +for all runnables in a bunch:
+"rust-analyzer.runnables.extraEnv": {
+ "RUN_SLOW_TESTS": "1"
+}
+
+Or it is possible to specify vars more granularly:
+"rust-analyzer.runnables.extraEnv": [
+ {
+ // "mask": null, // null mask means that this rule will be applied for all runnables
+ env: {
+ "APP_ID": "1",
+ "APP_DATA": "asdf"
+ }
+ },
+ {
+ "mask": "test_name",
+ "env": {
+ "APP_ID": "2", // overwrites only APP_ID
+ }
+ }
+]
+
+You can use any valid regular expression as a mask. Also note that a
+full runnable name is something like run bin_or_example_name,
+test some::mod::test_name or test-mod some::mod, so it is
+possible to distinguish binaries, single tests, and test modules with
+this masks: "^run"
, "^test "
(the trailing space matters!), and
+"^test-mod"
respectively.
If needed, you can set different values for different platforms:
+"rust-analyzer.runnables.extraEnv": [
+ {
+ "platform": "win32", // windows only
+ env: {
+ "APP_DATA": "windows specific data"
+ }
+ },
+ {
+ "platform": ["linux"],
+ "env": {
+ "APP_DATA": "linux data",
+ }
+ },
+ { // for all platforms
+ "env": {
+ "APP_COMMON_DATA": "xxx",
+ }
+ }
+]
+
+Instead of relying on the built-in cargo check
, you can configure Code
+to run a command in the background and use the $rustc-watch
problem
+matcher to generate inline error markers from its output.
To do this you need to create a new VS Code
+Task and set
+"rust-analyzer.checkOnSave": false
in preferences.
For example, if you want to run
+cargo watch
instead, you might
+add the following to .vscode/tasks.json
:
{
+ "label": "Watch",
+ "group": "build",
+ "type": "shell",
+ "command": "cargo watch",
+ "problemMatcher": "$rustc-watch",
+ "isBackground": true
+}
+
+VS Code Live Share has partial support for rust-analyzer.
+Live Share requires the official Microsoft build of VS Code, OSS +builds will not work correctly.
+The host’s rust-analyzer instance will be shared with all guests joining +the session. The guests do not have to have the rust-analyzer extension +installed for this to work.
+If you are joining a Live Share session and do have rust-analyzer +installed locally, commands from the command palette will not work +correctly since they will attempt to communicate with the local server.
+ +Source: annotations.rs
+Provides user with annotations above items for looking up references or impl blocks +and running/debugging binaries.
+ +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
and core
crate
self
super
Example:
+use std::fs::File;
+
+use itertools::Itertools;
+use syntax::ast;
+
+use crate::utils::insert_use;
+
+use self::auto_import;
+
+use super::AssistContext;
+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 as item
.In VS Code
the configuration for this is rust-analyzer.imports.granularity.group
.
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 the crate
+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 with self
. This will result in paths that always start with either crate
, 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
.
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.
+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).
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.
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.
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.
Source: view_item_tree.rs
+Displays the ItemTree of the currently open file, for debugging.
+Editor | Action Name |
---|---|
VS Code | rust-analyzer: Debug ItemTree |
Source: expand_macro.rs
+Shows the full macro expansion of the macro at current cursor.
+Editor | Action Name |
---|---|
VS Code | rust-analyzer: Expand macro recursively |
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+← |
Source: file_structure.rs
+Provides a tree of the symbols defined in the file. Can be used to
+Editor | Shortcut |
---|---|
VS Code | Ctrl+Shift+O |
Source: references.rs
+Shows all references of the item at the cursor location
+Editor | Shortcut |
---|---|
VS Code | Shift+Alt+F12 |
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.
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!(...)
Source: goto_declaration.rs
+Navigates to the declaration of an identifier.
+This is the same as Go to Definition
with the following exceptions:
mod name;
item declarationSource: 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 |
Source: goto_implementation.rs
+Navigates to the impl blocks of types.
+Editor | Shortcut |
---|---|
VS Code | Ctrl+F12 |
Source: goto_type_definition.rs
+Navigates to the type of an identifier.
+Editor | Action Name |
---|---|
VS Code | Go to Type Definition |
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
or await token, highlights all yield points for that async context . if on a
returnor
fnkeyword,
?character or
->return type arrow, highlights all exit points for that context . if on a
break,
loop,
whileor
fortoken, highlights all break points for that loop or block context . if on a
moveor
|` token that belongs to a closure, highlights all captures of the closure.
Note: ?
, |
and ->
do not currently trigger this behavior in the VSCode editor.
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.
+ +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
+Optionally, one can enable additional hints for
+Source: interpret_function.rs
+Editor | Action Name |
---|---|
VS Code | rust-analyzer: Interpret Function |
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 |
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 {}
or if let ... {}
for Option
or Result
expr.match
-> match expr {}
expr.while
-> while expr {}
or while let ... {}
for Option
or Result
expr.ref
-> &expr
expr.refm
-> &mut expr
expr.let
-> let $0 = expr;
expr.letm
-> let mut $0 = expr;
expr.not
-> !expr
expr.dbg
-> dbg!(expr)
expr.dbgr
-> dbg!(&expr)
expr.call
-> (expr)
There also snippet completions:
+pd
-> eprintln!(" = {:?}", );
ppd
-> eprintln!(" = {:#?}", );
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.
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 |
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) |
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 |
Source: on_enter.rs
+rust-analyzer can override kbd:[Enter] key to make it smarter:
+///
//
inserts //
//!
doc comments automatically inserts //!
{
indents contents and closing }
of single-line blockThis 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'"
+}
+
+
+Source: typing.rs
+Some features trigger on typing certain characters:
+let =
tries to smartly add ;
if =
is followed by an existing expression=
between two expressions adds ;
when in statement position=
to turn an assignment into an equality comparison removes ;
when in expression position.
in a chain method call auto-indents{
or (
in front of an expression inserts a closing }
or )
after the expression{
in a use item adds a closing }
in the right placeVS Code::
+Add the following to settings.json
:
"editor.formatOnType": true,
+
++
+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 |
Source: parent_module.rs
+Navigates to the parent module of the current module.
+Editor | Action Name |
---|---|
VS Code | rust-analyzer: Locate parent module |
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 |
Source: rename.rs
+Renames the item below the cursor and all of its references
+Editor | Shortcut |
---|---|
VS Code | F2 |
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 |
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.
Rust-analyzer currently emits the following token tags:
+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. |
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. |
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 ` |
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 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* taits. |
constant | Emitted for const. |
consuming | Emitted for locals that are being consumed when use in a fuction 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 sourc 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 tking &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. |
+
+Source: fetch_crates.rs
+Shows a view tree with all the dependencies of this project
+Editor | Panel Name |
---|---|
VS Code | Rust Dependencies |
Source: syntax_tree.rs
+Shows the parse tree of the current file. It exists mostly for debugging +rust-analyzer itself.
+Editor | Action Name |
---|---|
VS Code | rust-analyzer: Show Syntax Tree |
Source: shuffle_crate_graph.rs
+Randomizes all crate IDs in the crate graph, for debugging.
+Editor | Action Name |
---|---|
VS Code | rust-analyzer: Shuffle Crate Graph |
Source: status.rs
+Shows internal statistic about memory usage of rust-analyzer.
+Editor | Action Name |
---|---|
VS Code | rust-analyzer: Status |
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)
+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.
+Using postfix
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.
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 |
Source: view_hir.rs
+Editor | Action Name |
---|---|
VS Code | rust-analyzer: View Hir |
Source: view_memory_layout.rs
+Displays the recursive memory layout of a datatype.
+Editor | Action Name |
---|---|
VS Code | rust-analyzer: View Memory Layout |
Source: view_mir.rs
+Editor | Action Name |
---|---|
VS Code | rust-analyzer: View Mir |
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 for Foo
type in the current workspacefoo#
searches for foo
function in the current workspaceFoo*
searches for Foo
type among dependencies, including stdlib
foo#*
searches for foo
function among dependenciesThat 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.
Editor | Shortcut |
---|---|
VS Code | Ctrl+T |
At its core, rust-analyzer is a library for semantic analysis of +Rust code as it changes over time. This manual focuses on a specific +usage of the library — running it as part of a server that implements +the Language Server +Protocol (LSP). +The LSP allows various code editors, like VS Code, Emacs or Vim, to +implement semantic features like completion or goto definition by +talking to an external language server process.
+To improve this document, send a pull request:
+https://github.com/rust-analyzer/…/manual.adoc
The manual is written in AsciiDoc and includes
+some extra files which are generated from the source code. Run
+cargo test
and cargo test -p xtask
to create these and then
+asciidoctor manual.adoc
to create an HTML copy.
If you have questions about using rust-analyzer, please ask them in the +“IDEs and Editors” topic of Rust +users forum.
+ +