From 5315934d888797432d62ec4a55303aeacb8cd286 Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Wed, 3 Jun 2020 18:22:05 +0200
Subject: [PATCH] Don't store generated docs in the repo

---
 .gitignore                            |    2 +
 docs/user/generated_assists.adoc      | 1015 -------------------------
 docs/user/generated_features.adoc     |  298 --------
 xtask/src/codegen.rs                  |    6 +-
 xtask/src/codegen/gen_assists_docs.rs |   11 +-
 xtask/src/lib.rs                      |    2 +
 xtask/src/main.rs                     |    1 +
 xtask/tests/tidy.rs                   |    9 +-
 8 files changed, 16 insertions(+), 1328 deletions(-)
 delete mode 100644 docs/user/generated_assists.adoc
 delete mode 100644 docs/user/generated_features.adoc

diff --git a/.gitignore b/.gitignore
index dab51647db7..aef0fac3397 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,5 @@ crates/*/target
 *.iml
 .vscode/settings.json
 *.html
+generated_assists.adoc
+generated_features.adoc
diff --git a/docs/user/generated_assists.adoc b/docs/user/generated_assists.adoc
deleted file mode 100644
index 4d2fb31d484..00000000000
--- a/docs/user/generated_assists.adoc
+++ /dev/null
@@ -1,1015 +0,0 @@
-[discrete]
-=== `add_custom_impl`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_custom_impl.rs#L14[add_custom_impl.rs]
-
-Adds impl block for derived trait.
-
-.Before
-```rust
-#[derive(Deb┃ug, Display)]
-struct S;
-```
-
-.After
-```rust
-#[derive(Display)]
-struct S;
-
-impl Debug for S {
-    $0
-}
-```
-
-
-[discrete]
-=== `add_derive`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_derive.rs#L9[add_derive.rs]
-
-Adds a new `#[derive()]` clause to a struct or enum.
-
-.Before
-```rust
-struct Point {
-    x: u32,
-    y: u32,┃
-}
-```
-
-.After
-```rust
-#[derive($0)]
-struct Point {
-    x: u32,
-    y: u32,
-}
-```
-
-
-[discrete]
-=== `add_explicit_type`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_explicit_type.rs#L9[add_explicit_type.rs]
-
-Specify type for a let binding.
-
-.Before
-```rust
-fn main() {
-    let x┃ = 92;
-}
-```
-
-.After
-```rust
-fn main() {
-    let x: i32 = 92;
-}
-```
-
-
-[discrete]
-=== `add_from_impl_for_enum`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs#L7[add_from_impl_for_enum.rs]
-
-Adds a From impl for an enum variant with one tuple field.
-
-.Before
-```rust
-enum A { ┃One(u32) }
-```
-
-.After
-```rust
-enum A { One(u32) }
-
-impl From<u32> for A {
-    fn from(v: u32) -> Self {
-        A::One(v)
-    }
-}
-```
-
-
-[discrete]
-=== `add_function`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_function.rs#L19[add_function.rs]
-
-Adds a stub function with a signature matching the function under the cursor.
-
-.Before
-```rust
-struct Baz;
-fn baz() -> Baz { Baz }
-fn foo() {
-    bar┃("", baz());
-}
-
-```
-
-.After
-```rust
-struct Baz;
-fn baz() -> Baz { Baz }
-fn foo() {
-    bar("", baz());
-}
-
-fn bar(arg: &str, baz: Baz) {
-    ${0:todo!()}
-}
-
-```
-
-
-[discrete]
-=== `add_hash`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/raw_string.rs#L65[raw_string.rs]
-
-Adds a hash to a raw string literal.
-
-.Before
-```rust
-fn main() {
-    r#"Hello,┃ World!"#;
-}
-```
-
-.After
-```rust
-fn main() {
-    r##"Hello, World!"##;
-}
-```
-
-
-[discrete]
-=== `add_impl`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_impl.rs#L6[add_impl.rs]
-
-Adds a new inherent impl for a type.
-
-.Before
-```rust
-struct Ctx<T: Clone> {
-    data: T,┃
-}
-```
-
-.After
-```rust
-struct Ctx<T: Clone> {
-    data: T,
-}
-
-impl<T: Clone> Ctx<T> {
-    $0
-}
-```
-
-
-[discrete]
-=== `add_impl_default_members`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_missing_impl_members.rs#L64[add_missing_impl_members.rs]
-
-Adds scaffold for overriding default impl members.
-
-.Before
-```rust
-trait Trait {
-    Type X;
-    fn foo(&self);
-    fn bar(&self) {}
-}
-
-impl Trait for () {
-    Type X = ();
-    fn foo(&self) {}┃
-
-}
-```
-
-.After
-```rust
-trait Trait {
-    Type X;
-    fn foo(&self);
-    fn bar(&self) {}
-}
-
-impl Trait for () {
-    Type X = ();
-    fn foo(&self) {}
-    $0fn bar(&self) {}
-
-}
-```
-
-
-[discrete]
-=== `add_impl_missing_members`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_missing_impl_members.rs#L24[add_missing_impl_members.rs]
-
-Adds scaffold for required impl members.
-
-.Before
-```rust
-trait Trait<T> {
-    Type X;
-    fn foo(&self) -> T;
-    fn bar(&self) {}
-}
-
-impl Trait<u32> for () {┃
-
-}
-```
-
-.After
-```rust
-trait Trait<T> {
-    Type X;
-    fn foo(&self) -> T;
-    fn bar(&self) {}
-}
-
-impl Trait<u32> for () {
-    fn foo(&self) -> u32 {
-        ${0:todo!()}
-    }
-
-}
-```
-
-
-[discrete]
-=== `add_new`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_new.rs#L12[add_new.rs]
-
-Adds a new inherent impl for a type.
-
-.Before
-```rust
-struct Ctx<T: Clone> {
-     data: T,┃
-}
-```
-
-.After
-```rust
-struct Ctx<T: Clone> {
-     data: T,
-}
-
-impl<T: Clone> Ctx<T> {
-    fn $0new(data: T) -> Self { Self { data } }
-}
-
-```
-
-
-[discrete]
-=== `add_turbo_fish`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/add_turbo_fish.rs#L10[add_turbo_fish.rs]
-
-Adds `::<_>` to a call of a generic method or function.
-
-.Before
-```rust
-fn make<T>() -> T { todo!() }
-fn main() {
-    let x = make┃();
-}
-```
-
-.After
-```rust
-fn make<T>() -> T { todo!() }
-fn main() {
-    let x = make::<${0:_}>();
-}
-```
-
-
-[discrete]
-=== `apply_demorgan`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/apply_demorgan.rs#L5[apply_demorgan.rs]
-
-Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws).
-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 `&&`, with both operands being a negation of some kind.
-This means something of the form `!x` or `x != y`.
-
-.Before
-```rust
-fn main() {
-    if x != 4 ||┃ !y {}
-}
-```
-
-.After
-```rust
-fn main() {
-    if !(x == 4 && y) {}
-}
-```
-
-
-[discrete]
-=== `auto_import`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/auto_import.rs#L18[auto_import.rs]
-
-If the name is unresolved, provides all possible imports for it.
-
-.Before
-```rust
-fn main() {
-    let map = HashMap┃::new();
-}
-```
-
-.After
-```rust
-use std::collections::HashMap;
-
-fn main() {
-    let map = HashMap::new();
-}
-```
-
-
-[discrete]
-=== `change_return_type_to_result`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/change_return_type_to_result.rs#L8[change_return_type_to_result.rs]
-
-Change the function's return type to Result.
-
-.Before
-```rust
-fn foo() -> i32┃ { 42i32 }
-```
-
-.After
-```rust
-fn foo() -> Result<i32, ${0:_}> { Ok(42i32) }
-```
-
-
-[discrete]
-=== `change_visibility`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/change_visibility.rs#L14[change_visibility.rs]
-
-Adds or changes existing visibility specifier.
-
-.Before
-```rust
-┃fn frobnicate() {}
-```
-
-.After
-```rust
-pub(crate) fn frobnicate() {}
-```
-
-
-[discrete]
-=== `convert_to_guarded_return`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/early_return.rs#L21[early_return.rs]
-
-Replace a large conditional with a guarded return.
-
-.Before
-```rust
-fn main() {
-    ┃if cond {
-        foo();
-        bar();
-    }
-}
-```
-
-.After
-```rust
-fn main() {
-    if !cond {
-        return;
-    }
-    foo();
-    bar();
-}
-```
-
-
-[discrete]
-=== `fill_match_arms`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/fill_match_arms.rs#L14[fill_match_arms.rs]
-
-Adds missing clauses to a `match` expression.
-
-.Before
-```rust
-enum Action { Move { distance: u32 }, Stop }
-
-fn handle(action: Action) {
-    match action {
-        ┃
-    }
-}
-```
-
-.After
-```rust
-enum Action { Move { distance: u32 }, Stop }
-
-fn handle(action: Action) {
-    match action {
-        $0Action::Move { distance } => {}
-        Action::Stop => {}
-    }
-}
-```
-
-
-[discrete]
-=== `fix_visibility`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/fix_visibility.rs#L13[fix_visibility.rs]
-
-Makes inaccessible item public.
-
-.Before
-```rust
-mod m {
-    fn frobnicate() {}
-}
-fn main() {
-    m::frobnicate┃() {}
-}
-```
-
-.After
-```rust
-mod m {
-    $0pub(crate) fn frobnicate() {}
-}
-fn main() {
-    m::frobnicate() {}
-}
-```
-
-
-[discrete]
-=== `flip_binexpr`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/flip_binexpr.rs#L5[flip_binexpr.rs]
-
-Flips operands of a binary expression.
-
-.Before
-```rust
-fn main() {
-    let _ = 90 +┃ 2;
-}
-```
-
-.After
-```rust
-fn main() {
-    let _ = 2 + 90;
-}
-```
-
-
-[discrete]
-=== `flip_comma`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/flip_comma.rs#L5[flip_comma.rs]
-
-Flips two comma-separated items.
-
-.Before
-```rust
-fn main() {
-    ((1, 2),┃ (3, 4));
-}
-```
-
-.After
-```rust
-fn main() {
-    ((3, 4), (1, 2));
-}
-```
-
-
-[discrete]
-=== `flip_trait_bound`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/flip_trait_bound.rs#L9[flip_trait_bound.rs]
-
-Flips two trait bounds.
-
-.Before
-```rust
-fn foo<T: Clone +┃ Copy>() { }
-```
-
-.After
-```rust
-fn foo<T: Copy + Clone>() { }
-```
-
-
-[discrete]
-=== `inline_local_variable`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/inline_local_variable.rs#L13[inline_local_variable.rs]
-
-Inlines local variable.
-
-.Before
-```rust
-fn main() {
-    let x┃ = 1 + 2;
-    x * 4;
-}
-```
-
-.After
-```rust
-fn main() {
-    (1 + 2) * 4;
-}
-```
-
-
-[discrete]
-=== `introduce_named_lifetime`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/introduce_named_lifetime.rs#L12[introduce_named_lifetime.rs]
-
-Change an anonymous lifetime to a named lifetime.
-
-.Before
-```rust
-impl Cursor<'_┃> {
-    fn node(self) -> &SyntaxNode {
-        match self {
-            Cursor::Replace(node) | Cursor::Before(node) => node,
-        }
-    }
-}
-```
-
-.After
-```rust
-impl<'a> Cursor<'a> {
-    fn node(self) -> &SyntaxNode {
-        match self {
-            Cursor::Replace(node) | Cursor::Before(node) => node,
-        }
-    }
-}
-```
-
-
-[discrete]
-=== `introduce_variable`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/introduce_variable.rs#L14[introduce_variable.rs]
-
-Extracts subexpression into a variable.
-
-.Before
-```rust
-fn main() {
-    ┃(1 + 2)┃ * 4;
-}
-```
-
-.After
-```rust
-fn main() {
-    let $0var_name = (1 + 2);
-    var_name * 4;
-}
-```
-
-
-[discrete]
-=== `invert_if`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/invert_if.rs#L12[invert_if.rs]
-
-Apply invert_if
-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`.
-
-.Before
-```rust
-fn main() {
-    if┃ !y { A } else { B }
-}
-```
-
-.After
-```rust
-fn main() {
-    if y { B } else { A }
-}
-```
-
-
-[discrete]
-=== `make_raw_string`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/raw_string.rs#L10[raw_string.rs]
-
-Adds `r#` to a plain string literal.
-
-.Before
-```rust
-fn main() {
-    "Hello,┃ World!";
-}
-```
-
-.After
-```rust
-fn main() {
-    r#"Hello, World!"#;
-}
-```
-
-
-[discrete]
-=== `make_usual_string`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/raw_string.rs#L39[raw_string.rs]
-
-Turns a raw string into a plain string.
-
-.Before
-```rust
-fn main() {
-    r#"Hello,┃ "World!""#;
-}
-```
-
-.After
-```rust
-fn main() {
-    "Hello, \"World!\"";
-}
-```
-
-
-[discrete]
-=== `merge_imports`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/merge_imports.rs#L14[merge_imports.rs]
-
-Merges two imports with a common prefix.
-
-.Before
-```rust
-use std::┃fmt::Formatter;
-use std::io;
-```
-
-.After
-```rust
-use std::{fmt::Formatter, io};
-```
-
-
-[discrete]
-=== `merge_match_arms`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/merge_match_arms.rs#L11[merge_match_arms.rs]
-
-Merges identical match arms.
-
-.Before
-```rust
-enum Action { Move { distance: u32 }, Stop }
-
-fn handle(action: Action) {
-    match action {
-        ┃Action::Move(..) => foo(),
-        Action::Stop => foo(),
-    }
-}
-```
-
-.After
-```rust
-enum Action { Move { distance: u32 }, Stop }
-
-fn handle(action: Action) {
-    match action {
-        Action::Move(..) | Action::Stop => foo(),
-    }
-}
-```
-
-
-[discrete]
-=== `move_arm_cond_to_match_guard`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/move_guard.rs#L56[move_guard.rs]
-
-Moves if expression from match arm body into a guard.
-
-.Before
-```rust
-enum Action { Move { distance: u32 }, Stop }
-
-fn handle(action: Action) {
-    match action {
-        Action::Move { distance } => ┃if distance > 10 { foo() },
-        _ => (),
-    }
-}
-```
-
-.After
-```rust
-enum Action { Move { distance: u32 }, Stop }
-
-fn handle(action: Action) {
-    match action {
-        Action::Move { distance } if distance > 10 => foo(),
-        _ => (),
-    }
-}
-```
-
-
-[discrete]
-=== `move_bounds_to_where_clause`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/move_bounds.rs#L10[move_bounds.rs]
-
-Moves inline type bounds to a where clause.
-
-.Before
-```rust
-fn apply<T, U, ┃F: FnOnce(T) -> U>(f: F, x: T) -> U {
-    f(x)
-}
-```
-
-.After
-```rust
-fn apply<T, U, F>(f: F, x: T) -> U where F: FnOnce(T) -> U {
-    f(x)
-}
-```
-
-
-[discrete]
-=== `move_guard_to_arm_body`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/move_guard.rs#L8[move_guard.rs]
-
-Moves match guard into match arm body.
-
-.Before
-```rust
-enum Action { Move { distance: u32 }, Stop }
-
-fn handle(action: Action) {
-    match action {
-        Action::Move { distance } ┃if distance > 10 => foo(),
-        _ => (),
-    }
-}
-```
-
-.After
-```rust
-enum Action { Move { distance: u32 }, Stop }
-
-fn handle(action: Action) {
-    match action {
-        Action::Move { distance } => if distance > 10 { foo() },
-        _ => (),
-    }
-}
-```
-
-
-[discrete]
-=== `remove_dbg`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/remove_dbg.rs#L8[remove_dbg.rs]
-
-Removes `dbg!()` macro call.
-
-.Before
-```rust
-fn main() {
-    ┃dbg!(92);
-}
-```
-
-.After
-```rust
-fn main() {
-    92;
-}
-```
-
-
-[discrete]
-=== `remove_hash`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/raw_string.rs#L89[raw_string.rs]
-
-Removes a hash from a raw string literal.
-
-.Before
-```rust
-fn main() {
-    r#"Hello,┃ World!"#;
-}
-```
-
-.After
-```rust
-fn main() {
-    r"Hello, World!";
-}
-```
-
-
-[discrete]
-=== `remove_mut`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/remove_mut.rs#L5[remove_mut.rs]
-
-Removes the `mut` keyword.
-
-.Before
-```rust
-impl Walrus {
-    fn feed(&mut┃ self, amount: u32) {}
-}
-```
-
-.After
-```rust
-impl Walrus {
-    fn feed(&self, amount: u32) {}
-}
-```
-
-
-[discrete]
-=== `reorder_fields`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/reorder_fields.rs#L10[reorder_fields.rs]
-
-Reorder the fields of record literals and record patterns in the same order as in
-the definition.
-
-.Before
-```rust
-struct Foo {foo: i32, bar: i32};
-const test: Foo = ┃Foo {bar: 0, foo: 1}
-```
-
-.After
-```rust
-struct Foo {foo: i32, bar: i32};
-const test: Foo = Foo {foo: 1, bar: 0}
-```
-
-
-[discrete]
-=== `replace_if_let_with_match`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/replace_if_let_with_match.rs#L13[replace_if_let_with_match.rs]
-
-Replaces `if let` with an else branch with a `match` expression.
-
-.Before
-```rust
-enum Action { Move { distance: u32 }, Stop }
-
-fn handle(action: Action) {
-    ┃if let Action::Move { distance } = action {
-        foo(distance)
-    } else {
-        bar()
-    }
-}
-```
-
-.After
-```rust
-enum Action { Move { distance: u32 }, Stop }
-
-fn handle(action: Action) {
-    match action {
-        Action::Move { distance } => foo(distance),
-        _ => bar(),
-    }
-}
-```
-
-
-[discrete]
-=== `replace_let_with_if_let`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/replace_let_with_if_let.rs#L14[replace_let_with_if_let.rs]
-
-Replaces `let` with an `if-let`.
-
-.Before
-```rust
-
-fn main(action: Action) {
-    ┃let x = compute();
-}
-
-fn compute() -> Option<i32> { None }
-```
-
-.After
-```rust
-
-fn main(action: Action) {
-    if let Some(x) = compute() {
-    }
-}
-
-fn compute() -> Option<i32> { None }
-```
-
-
-[discrete]
-=== `replace_qualified_name_with_use`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs#L6[replace_qualified_name_with_use.rs]
-
-Adds a use statement for a given fully-qualified name.
-
-.Before
-```rust
-fn process(map: std::collections::┃HashMap<String, String>) {}
-```
-
-.After
-```rust
-use std::collections::HashMap;
-
-fn process(map: HashMap<String, String>) {}
-```
-
-
-[discrete]
-=== `replace_unwrap_with_match`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/replace_unwrap_with_match.rs#L17[replace_unwrap_with_match.rs]
-
-Replaces `unwrap` a `match` expression. Works for Result and Option.
-
-.Before
-```rust
-enum Result<T, E> { Ok(T), Err(E) }
-fn main() {
-    let x: Result<i32, i32> = Result::Ok(92);
-    let y = x.┃unwrap();
-}
-```
-
-.After
-```rust
-enum Result<T, E> { Ok(T), Err(E) }
-fn main() {
-    let x: Result<i32, i32> = Result::Ok(92);
-    let y = match x {
-        Ok(a) => a,
-        $0_ => unreachable!(),
-    };
-}
-```
-
-
-[discrete]
-=== `split_import`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/split_import.rs#L7[split_import.rs]
-
-Wraps the tail of import into braces.
-
-.Before
-```rust
-use std::┃collections::HashMap;
-```
-
-.After
-```rust
-use std::{collections::HashMap};
-```
-
-
-[discrete]
-=== `unwrap_block`
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_assists/src/handlers/unwrap_block.rs#L9[unwrap_block.rs]
-
-This assist removes if...else, for, while and loop control statements to just keep the body.
-
-.Before
-```rust
-fn foo() {
-    if true {┃
-        println!("foo");
-    }
-}
-```
-
-.After
-```rust
-fn foo() {
-    println!("foo");
-}
-```
diff --git a/docs/user/generated_features.adoc b/docs/user/generated_features.adoc
deleted file mode 100644
index 4b93b759fa4..00000000000
--- a/docs/user/generated_features.adoc
+++ /dev/null
@@ -1,298 +0,0 @@
-=== Expand Macro Recursively
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/expand_macro.rs#L15[expand_macro.rs]
-
-Shows the full macro expansion of the macro at current cursor.
-
-|===
-| Editor  | Action Name
-
-| VS Code | **Rust Analyzer: Expand macro recursively**
-|===
-
-
-=== Extend Selection
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/extend_selection.rs#L15[extend_selection.rs]
-
-Extends the current selection to the encompassing syntactic construct
-(expression, statement, item, module, etc). It works with multiple cursors.
-
-|===
-| Editor  | Shortcut
-
-| VS Code | kbd:[Ctrl+Shift+→]
-|===
-
-
-=== File Structure
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/display/structure.rs#L17[structure.rs]
-
-Provides a tree of the symbols defined in the file. Can be used to
-
-* fuzzy search symbol in a file (super useful)
-* draw breadcrumbs to describe the context around the cursor
-* draw outline of the file
-
-|===
-| Editor  | Shortcut
-
-| VS Code | kbd:[Ctrl+Shift+O]
-|===
-
-
-=== Go to Definition
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/goto_definition.rs#L18[goto_definition.rs]
-
-Navigates to the definition of an identifier.
-
-|===
-| Editor  | Shortcut
-
-| VS Code | kbd:[F12]
-|===
-
-
-=== Go to Implementation
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/goto_implementation.rs#L7[goto_implementation.rs]
-
-Navigates to the impl block of structs, enums or traits. Also implemented as a code lens.
-
-|===
-| Editor  | Shortcut
-
-| VS Code | kbd:[Ctrl+F12]
-|===
-
-
-=== Go to Type Definition
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/goto_type_definition.rs#L6[goto_type_definition.rs]
-
-Navigates to the type of an identifier.
-
-|===
-| Editor  | Action Name
-
-| VS Code | **Go to Type Definition*
-|===
-
-
-=== Hover
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/hover.rs#L58[hover.rs]
-
-Shows additional information, like type of an expression or documentation for definition when "focusing" code.
-Focusing is usually hovering with a mouse, but can also be triggered with a shortcut.
-
-
-=== Inlay Hints
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/inlay_hints.rs#L40[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 shows hits for
-
-* types of local variables
-* names of function arguments
-* types of chained expressions
-
-**Note:** VS Code does not have native support for inlay hints https://github.com/microsoft/vscode/issues/16221[yet] and the hints are implemented using decorations.
-This approach has limitations, the caret movement and bracket highlighting near the edges of the hint may be weird:
-https://github.com/rust-analyzer/rust-analyzer/issues/1623[1], https://github.com/rust-analyzer/rust-analyzer/issues/3453[2].
-
-|===
-| Editor  | Action Name
-
-| VS Code | **Rust Analyzer: Toggle inlay hints*
-|===
-
-
-=== Join Lines
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/join_lines.rs#L12[join_lines.rs]
-
-Join selected lines into one, smartly fixing up whitespace, trailing commas, and braces.
-
-|===
-| Editor  | Action Name
-
-| VS Code | **Rust Analyzer: Join lines**
-|===
-
-
-=== Magic Completions
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/completion.rs#L38[completion.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.not` -> `!expr`
-- `expr.dbg` -> `dbg!(expr)`
-
-There also snippet completions:
-
-.Expressions
-- `pd` -> `println!("{:?}")`
-- `ppd` -> `println!("{:#?}")`
-
-.Items
-- `tfn` -> `#[test] fn f(){}`
-- `tmod` ->
-```rust
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn test_fn() {}
-}
-```
-
-
-=== Matching Brace
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/matching_brace.rs#L3[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**
-|===
-
-
-=== On Typing Assists
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/typing.rs#L35[typing.rs]
-
-Some features trigger on typing certain characters:
-
-- typing `let =` tries to smartly add `;` if `=` is followed by an existing expression
-- Enter inside comments automatically inserts `///`
-- typing `.` in a chain method call auto-indents
-
-
-=== Parent Module
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/parent_module.rs#L12[parent_module.rs]
-
-Navigates to the parent module of the current module.
-
-|===
-| Editor  | Action Name
-
-| VS Code | **Rust Analyzer: Locate parent module**
-|===
-
-
-=== Run
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/runnables.rs#L45[runnables.rs]
-
-Shows a popup suggesting to run a test/benchmark/binary **at the current cursor
-location**. Super useful for repeatedly running just a single test. Do bind this
-to a shortcut!
-
-|===
-| Editor  | Action Name
-
-| VS Code | **Rust Analyzer: Run**
-|===
-
-
-=== Semantic Syntax Highlighting
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/syntax_highlighting.rs#L33[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 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.
-
-
-=== Show Syntax Tree
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/syntax_tree.rs#L9[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**
-|===
-
-
-=== Status
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/status.rs#L27[status.rs]
-
-Shows internal statistic about memory usage of rust-analyzer.
-
-|===
-| Editor  | Action Name
-
-| VS Code | **Rust Analyzer: Status**
-|===
-
-
-=== Structural Seach and Replace
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/ssr.rs#L26[ssr.rs]
-
-Search and replace with named wildcards that will match any expression.
-The syntax for a structural search replace command is `<search_pattern> ==>> <replace_pattern>`.
-A `$<name>:expr` placeholder in the search pattern will match any expression and `$<name>` will reference it in the replacement.
-Available via the command `rust-analyzer.ssr`.
-
-```rust
-// Using structural search replace command [foo($a:expr, $b:expr) ==>> ($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**
-|===
-
-
-=== Workspace Symbol
-**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide_db/src/symbol_index.rs#L113[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 workspace
-- `foo#` searches for `foo` function in the current workspace
-- `Foo*` searches for `Foo` type among dependencies, including `stdlib`
-- `foo#*` searches for `foo` function among dependencies
-
-That is, `#` switches from "types" to all symbols, `*` switches from the current
-workspace to dependencies.
-
-|===
-| Editor  | Shortcut
-
-| VS Code | kbd:[Ctrl+T]
-|===
diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs
index 5511c01d548..f5f4b964a4c 100644
--- a/xtask/src/codegen.rs
+++ b/xtask/src/codegen.rs
@@ -18,8 +18,10 @@ use std::{
 use crate::{not_bash::fs2, project_root, Result};
 
 pub use self::{
-    gen_assists_docs::generate_assists_docs, gen_feature_docs::generate_feature_docs,
-    gen_parser_tests::generate_parser_tests, gen_syntax::generate_syntax,
+    gen_assists_docs::{generate_assists_docs, generate_assists_tests},
+    gen_feature_docs::generate_feature_docs,
+    gen_parser_tests::generate_parser_tests,
+    gen_syntax::generate_syntax,
 };
 
 const GRAMMAR_DIR: &str = "crates/ra_parser/src/grammar";
diff --git a/xtask/src/codegen/gen_assists_docs.rs b/xtask/src/codegen/gen_assists_docs.rs
index 6c1be53503d..526941f73ac 100644
--- a/xtask/src/codegen/gen_assists_docs.rs
+++ b/xtask/src/codegen/gen_assists_docs.rs
@@ -7,16 +7,17 @@ use crate::{
     project_root, rust_files, Result,
 };
 
+pub fn generate_assists_tests(mode: Mode) -> Result<()> {
+    let assists = Assist::collect()?;
+    generate_tests(&assists, mode)
+}
+
 pub fn generate_assists_docs(mode: Mode) -> Result<()> {
     let assists = Assist::collect()?;
-    generate_tests(&assists, mode)?;
-
     let contents = assists.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n");
     let contents = contents.trim().to_string() + "\n";
     let dst = project_root().join("docs/user/generated_assists.adoc");
-    codegen::update(&dst, &contents, mode)?;
-
-    Ok(())
+    codegen::update(&dst, &contents, mode)
 }
 
 #[derive(Debug)]
diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs
index 874957885e8..739f49f7be8 100644
--- a/xtask/src/lib.rs
+++ b/xtask/src/lib.rs
@@ -160,6 +160,8 @@ pub fn run_release(dry_run: bool) -> Result<()> {
         run!("git reset --hard tags/nightly")?;
         run!("git push")?;
     }
+    codegen::generate_assists_docs(Mode::Overwrite)?;
+    codegen::generate_feature_docs(Mode::Overwrite)?;
 
     let website_root = project_root().join("../rust-analyzer.github.io");
     let changelog_dir = website_root.join("./thisweek/_posts");
diff --git a/xtask/src/main.rs b/xtask/src/main.rs
index 9d7cdd1145a..81bb3a33f29 100644
--- a/xtask/src/main.rs
+++ b/xtask/src/main.rs
@@ -74,6 +74,7 @@ FLAGS:
             args.finish()?;
             codegen::generate_syntax(Mode::Overwrite)?;
             codegen::generate_parser_tests(Mode::Overwrite)?;
+            codegen::generate_assists_tests(Mode::Overwrite)?;
             codegen::generate_assists_docs(Mode::Overwrite)?;
             codegen::generate_feature_docs(Mode::Overwrite)?;
             Ok(())
diff --git a/xtask/tests/tidy.rs b/xtask/tests/tidy.rs
index 62626064ee5..d38ac7f17e7 100644
--- a/xtask/tests/tidy.rs
+++ b/xtask/tests/tidy.rs
@@ -25,18 +25,11 @@ fn generated_tests_are_fresh() {
 
 #[test]
 fn generated_assists_are_fresh() {
-    if let Err(error) = codegen::generate_assists_docs(Mode::Verify) {
+    if let Err(error) = codegen::generate_assists_tests(Mode::Verify) {
         panic!("{}. Please update assists by running `cargo xtask codegen`", error);
     }
 }
 
-#[test]
-fn generated_features_are_fresh() {
-    if let Err(error) = codegen::generate_feature_docs(Mode::Verify) {
-        panic!("{}. Please update features by running `cargo xtask codegen`", error);
-    }
-}
-
 #[test]
 fn check_code_formatting() {
     if let Err(error) = run_rustfmt(Mode::Verify) {