Repository: rust-lang/rust-analyzer
Pull request #12060 (2022-04-23 00:28:24)

minor: Simplify
bors r+


Patch:
diff --git a/.cargo/config.toml b/.cargo/config
similarity index 79%
rename from .cargo/config.toml
rename to .cargo/config
index 982c78cd25..1447614b76 100644
--- a/.cargo/config.toml
+++ b/.cargo/config
@@ -1,5 +1,6 @@
 [alias]
 xtask = "run --package xtask --bin xtask --"
+install-ra = "run --package xtask --bin xtask -- install" # for backwards compat
 tq = "test -- -q"
 qt = "tq"
 lint = "clippy --all-targets -- -Aclippy::collapsible_if -Aclippy::needless_pass_by_value -Aclippy::nonminimal_bool -Aclippy::redundant_pattern_matching --cap-lints warn"
diff --git a/crates/hir_def/src/db.rs b/crates/hir_def/src/db.rs
index df6dcb024b..74bb7472d5 100644
--- a/crates/hir_def/src/db.rs
+++ b/crates/hir_def/src/db.rs
@@ -18,7 +18,7 @@ use crate::{
     generics::GenericParams,
     import_map::ImportMap,
     intern::Interned,
-    item_tree::{AttrOwner, ItemTree},
+    item_tree::ItemTree,
     lang_item::{LangItemTarget, LangItems},
     nameres::DefMap,
     visibility::{self, Visibility},
@@ -184,8 +184,6 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
 
     #[salsa::transparent]
     fn crate_limits(&self, crate_id: CrateId) -> CrateLimits;
-
-    fn crate_supports_no_std(&self, crate_id: CrateId) -> bool;
 }
 
 fn crate_def_map_wait(db: &dyn DefDatabase, krate: CrateId) -> Arc<DefMap> {
@@ -206,38 +204,3 @@ fn crate_limits(db: &dyn DefDatabase, crate_id: CrateId) -> CrateLimits {
         recursion_limit: def_map.recursion_limit().unwrap_or(128),
     }
 }
-
-fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: CrateId) -> bool {
-    let file = db.crate_graph()[crate_id].root_file_id;
-    let item_tree = db.file_item_tree(file.into());
-    let attrs = item_tree.raw_attrs(AttrOwner::TopLevel);
-    for attr in &**attrs {
-        match attr.path().as_ident().and_then(|id| id.as_text()) {
-            Some(ident) if ident == "no_std" => return true,
-            Some(ident) if ident == "cfg_attr" => {}
-            _ => continue,
-        }
-
-        // This is a `cfg_attr`; check if it could possibly expand to `no_std`.
-        // Syntax is: `#[cfg_attr(condition(cfg, style), attr0, attr1, <...>)]`
-        let tt = match attr.token_tree_value() {
-            Some(tt) => &tt.token_trees,
-            None => continue,
-        };
-
-        let segments = tt.split(|tt| match tt {
-            tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => true,
-            _ => false,
-        });
-        for output in segments.skip(1) {
-            match output {
-                [tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] if ident.text == "no_std" => {
-                    return true
-                }
-                _ => {}
-            }
-        }
-    }
-
-    false
-}
diff --git a/crates/hir_def/src/find_path.rs b/crates/hir_def/src/find_path.rs
index 89e961f84f..bb89b8cff4 100644
--- a/crates/hir_def/src/find_path.rs
+++ b/crates/hir_def/src/find_path.rs
@@ -43,7 +43,8 @@ impl ModPathExt for ModPath {
         self.segments().first() == Some(&known::std)
     }
 
-    // Can we replace the first segment with `std::` and still get a valid, identical path?
+    // When std library is present, paths starting with `std::`
+    // should be preferred over paths starting with `core::` and `alloc::`
     fn can_start_with_std(&self) -> bool {
         let first_segment = self.segments().first();
         first_segment == Some(&known::alloc) || first_segment == Some(&known::core)
@@ -202,7 +203,7 @@ fn find_path_inner_(
     }
 
     // - otherwise, look for modules containing (reexporting) it and import it from one of those
-    let prefer_no_std = db.crate_supports_no_std(crate_root.krate);
+    let prefer_no_std = db.attrs(crate_root.into()).by_key("no_std").exists();
     let mut best_path = None;
     let mut best_path_len = max_len;
 
@@ -829,32 +830,6 @@ pub mod fmt {
 
 //- /zzz.rs crate:core
 
-pub mod fmt {
-    pub struct Error;
-}
-        "#,
-            "core::fmt::Error",
-            "core::fmt::Error",
-            "core::fmt::Error",
-            "core::fmt::Error",
-        );
-
-        // Should also work (on a best-effort basis) if `no_std` is conditional.
-        check_found_path(
-            r#"
-//- /main.rs crate:main deps:core,std
-#![cfg_attr(not(test), no_std)]
-
-$0
-
-//- /std.rs crate:std deps:core
-
-pub mod fmt {
-    pub use core::fmt::Error;
-}
-
-//- /zzz.rs crate:core
-
 pub mod fmt {
     pub struct Error;
 }
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index a3787728ea..24eff4cc9a 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -681,31 +681,23 @@ impl<'a> TyLoweringContext<'a> {
 
         let ty_error = GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner);
 
-        let mut def_generic_iter = def_generics.iter_id();
-
-        for _ in 0..parent_params {
-            if let Some(eid) = def_generic_iter.next() {
-                match eid {
-                    Either::Left(_) => substs.push(ty_error.clone()),
-                    Either::Right(x) => {
-                        substs.push(unknown_const_as_generic(self.db.const_param_ty(x)))
-                    }
+        for eid in def_generics.iter_id().take(parent_params) {
+            match eid {
+                Either::Left(_) => substs.push(ty_error.clone()),
+                Either::Right(x) => {
+                    substs.push(unknown_const_as_generic(self.db.const_param_ty(x)))
                 }
             }
         }
 
         let fill_self_params = || {
-            for x in explicit_self_ty
-                .into_iter()
-                .map(|x| GenericArgData::Ty(x).intern(Interner))
-                .chain(iter::repeat(ty_error.clone()))
-                .take(self_params)
-            {
-                if let Some(id) = def_generic_iter.next() {
-                    assert!(id.is_left());
-                    substs.push(x);
-                }
-            }
+            substs.extend(
+                explicit_self_ty
+                    .into_iter()
+                    .map(|x| GenericArgData::Ty(x).intern(Interner))
+                    .chain(iter::repeat(ty_error.clone()))
+                    .take(self_params),
+            )
         };
         let mut had_explicit_args = false;
 
@@ -720,38 +712,34 @@ impl<'a> TyLoweringContext<'a> {
             };
             let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 };
             // if args are provided, it should be all of them, but we can't rely on that
-            for arg in generic_args
+            for (arg, id) in generic_args
                 .args
                 .iter()
                 .filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
                 .skip(skip)
                 .take(expected_num)
+                .zip(def_generics.iter_id().skip(parent_params + skip))
             {
-                if let Some(id) = def_generic_iter.next() {
-                    if let Some(x) = generic_arg_to_chalk(
-                        self.db,
-                        id,
-                        arg,
-                        &mut (),
-                        |_, type_ref| self.lower_ty(type_ref),
-                        |_, c, ty| {
-                            const_or_path_to_chalk(
-                                self.db,
-                                &self.resolver,
-                                ty,
-                                c,
-                                self.type_param_mode,
-                                || self.generics(),
-                                self.in_binders,
-                            )
-                        },
-                    ) {
-                        had_explicit_args = true;
-                        substs.push(x);
-                    } else {
-                        // we just filtered them out
-                        never!("Unexpected lifetime argument");
-                    }
+                if let Some(x) = generic_arg_to_chalk(
+                    self.db,
+                    id,
+                    arg,
+                    &mut (),
+                    |_, type_ref| self.lower_ty(type_ref),
+                    |_, c, ty| {
+                        const_or_path_to_chalk(
+                            self.db,
+                            &self.resolver,
+                            ty,
+                            c,
+                            self.type_param_mode,
+                            || self.generics(),
+                            self.in_binders,
+                        )
+                    },
+                ) {
+                    had_explicit_args = true;
+                    substs.push(x);
                 }
             }
         } else {
@@ -769,16 +757,14 @@ impl<'a> TyLoweringContext<'a> {
                 for default_ty in defaults.iter().skip(substs.len()) {
                     // each default can depend on the previous parameters
                     let substs_so_far = Substitution::from_iter(Interner, substs.clone());
-                    if let Some(_id) = def_generic_iter.next() {
-                        substs.push(default_ty.clone().substitute(Interner, &substs_so_far));
-                    }
+                    substs.push(default_ty.clone().substitute(Interner, &substs_so_far));
                 }
             }
         }
 
         // add placeholders for args that were not provided
         // FIXME: emit diagnostics in contexts where this is not allowed
-        for eid in def_generic_iter {
+        for eid in def_generics.iter_id().skip(substs.len()) {
             match eid {
                 Either::Left(_) => substs.push(ty_error.clone()),
                 Either::Right(x) => {
@@ -786,7 +772,6 @@ impl<'a> TyLoweringContext<'a> {
                 }
             }
         }
-        // If this assert fails, it means you pushed into subst but didn't call .next() of def_generic_iter
         assert_eq!(substs.len(), total_len);
 
         Substitution::from_iter(Interner, substs)
@@ -1674,10 +1659,6 @@ pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mut
     }
 }
 
-/// Checks if the provided generic arg matches its expected kind, then lower them via
-/// provided closures. Use unknown if there was kind mismatch.
-///
-/// Returns `Some` of the lowered generic arg. `None` if the provided arg is a lifetime.
 pub(crate) fn generic_arg_to_chalk<'a, T>(
     db: &dyn HirDatabase,
     kind_id: Either<TypeParamId, ConstParamId>,
diff --git a/crates/ide/src/ssr.rs b/crates/ide/src/ssr.rs
index ba9a7f62e6..6142a0eafd 100644
--- a/crates/ide/src/ssr.rs
+++ b/crates/ide/src/ssr.rs
@@ -45,7 +45,6 @@ pub(crate) fn ssr_assists(
             group: Some(GroupLabel("Apply SSR".into())),
             target: comment_range,
             source_change,
-            trigger_signature_help: false,
         };
 
         ssr_assists.push(assist);
@@ -141,7 +140,6 @@ mod tests {
                         is_snippet: false,
                     },
                 ),
-                trigger_signature_help: false,
             }
         "#]]
         .assert_debug_eq(&apply_in_file_assist);
@@ -188,7 +186,6 @@ mod tests {
                         is_snippet: false,
                     },
                 ),
-                trigger_signature_help: false,
             }
         "#]]
         .assert_debug_eq(&apply_in_workspace_assist);
@@ -228,7 +225,6 @@ mod tests {
                 ),
                 target: 10..21,
                 source_change: None,
-                trigger_signature_help: false,
             }
         "#]]
         .assert_debug_eq(&apply_in_file_assist);
@@ -248,7 +244,6 @@ mod tests {
                 ),
                 target: 10..21,
                 source_change: None,
-                trigger_signature_help: false,
             }
         "#]]
         .assert_debug_eq(&apply_in_workspace_assist);
diff --git a/crates/ide_assists/src/assist_context.rs b/crates/ide_assists/src/assist_context.rs
index ec85faaf46..fd46aa2479 100644
--- a/crates/ide_assists/src/assist_context.rs
+++ b/crates/ide_assists/src/assist_context.rs
@@ -193,11 +193,9 @@ impl Assists {
             return None;
         }
 
-        let mut trigger_signature_help = false;
         let source_change = if self.resolve.should_resolve(&id) {
             let mut builder = AssistBuilder::new(self.file);
             f(&mut builder);
-            trigger_signature_help = builder.trigger_signature_help;
             Some(builder.finish())
         } else {
             None
@@ -205,7 +203,7 @@ impl Assists {
 
         let label = Label::new(label);
         let group = group.cloned();
-        self.buf.push(Assist { id, label, group, target, source_change, trigger_signature_help });
+        self.buf.push(Assist { id, label, group, target, source_change });
         Some(())
     }
 
@@ -221,7 +219,6 @@ pub(crate) struct AssistBuilder {
     edit: TextEditBuilder,
     file_id: FileId,
     source_change: SourceChange,
-    trigger_signature_help: bool,
 
     /// Maps the original, immutable `SyntaxNode` to a `clone_for_update` twin.
     mutated_tree: Option<TreeMutator>,
@@ -255,7 +252,6 @@ impl AssistBuilder {
             edit: TextEdit::builder(),
             file_id,
             source_change: SourceChange::default(),
-            trigger_signature_help: false,
             mutated_tree: None,
         }
     }
@@ -336,9 +332,6 @@ impl AssistBuilder {
         let file_system_edit = FileSystemEdit::MoveFile { src, dst };
         self.source_change.push_file_system_edit(file_system_edit);
     }
-    pub(crate) fn trigger_signature_help(&mut self) {
-        self.trigger_signature_help = true;
-    }
 
     fn finish(mut self) -> SourceChange {
         self.commit();
diff --git a/crates/ide_assists/src/handlers/add_turbo_fish.rs b/crates/ide_assists/src/handlers/add_turbo_fish.rs
index a82dca9db0..c3d27f7ea6 100644
--- a/crates/ide_assists/src/handlers/add_turbo_fish.rs
+++ b/crates/ide_assists/src/handlers/add_turbo_fish.rs
@@ -89,18 +89,15 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<(
         AssistId("add_turbo_fish", AssistKind::RefactorRewrite),
         "Add `::<>`",
         ident.text_range(),
-        |builder| {
-            builder.trigger_signature_help();
-            match ctx.config.snippet_cap {
-                Some(cap) => {
-                    let snip = format!("::<{}>", get_snippet_fish_head(number_of_arguments));
-                    builder.insert_snippet(cap, ident.text_range().end(), snip)
-                }
-                None => {
-                    let fish_head = std::iter::repeat("_").take(number_of_arguments).format(", ");
-                    let snip = format!("::<{}>", fish_head);
-                    builder.insert(ident.text_range().end(), snip);
-                }
+        |builder| match ctx.config.snippet_cap {
+            Some(cap) => {
+                let snip = format!("::<{}>", get_snippet_fish_head(number_of_arguments));
+                builder.insert_snippet(cap, ident.text_range().end(), snip)
+            }
+            None => {
+                let fish_head = std::iter::repeat("_").take(number_of_arguments).format(", ");
+                let snip = format!("::<{}>", fish_head);
+                builder.insert(ident.text_range().end(), snip);
             }
         },
     )
diff --git a/crates/ide_completion/src/completions/fn_param.rs b/crates/ide_completion/src/completions/fn_param.rs
index ae09339e95..7e9c1f49de 100644
--- a/crates/ide_completion/src/completions/fn_param.rs
+++ b/crates/ide_completion/src/completions/fn_param.rs
@@ -5,7 +5,7 @@ use rustc_hash::FxHashMap;
 use syntax::{
     algo,
     ast::{self, HasModuleItem},
-    match_ast, AstNode, Direction, SyntaxKind, TextRange,
+    match_ast, AstNode, Direction, SyntaxKind,
 };
 
 use crate::{
@@ -27,13 +27,14 @@ pub(crate) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext)
 
     let comma_wrapper = comma_wrapper(ctx);
     let mut add_new_item_to_acc = |label: &str, lookup: String| {
-        let mk_item = |label: &str, range: TextRange| {
-            CompletionItem::new(CompletionItemKind::Binding, range, label)
+        let mk_item = |label: &str| {
+            CompletionItem::new(CompletionItemKind::Binding, ctx.source_range(), label)
         };
-        let item = match &comma_wrapper {
-            Some((fmt, range, lookup)) => mk_item(&fmt(label), *range).lookup_by(lookup).to_owned(),
-            None => mk_item(label, ctx.source_range()).lookup_by(lookup).to_owned(),
+        let mut item = match &comma_wrapper {
+            Some(fmt) => mk_item(&fmt(label)),
+            None => mk_item(label),
         };
+        item.lookup_by(lookup);
         item.add_to(acc)
     };
 
@@ -161,16 +162,14 @@ fn should_add_self_completions(ctx: &CompletionContext, param_list: &ast::ParamL
     inside_impl && no_params
 }
 
-fn comma_wrapper(ctx: &CompletionContext) -> Option<(impl Fn(&str) -> String, TextRange, String)> {
-    let param = ctx.token.ancestors().find(|node| node.kind() == SyntaxKind::PARAM)?;
-
+fn comma_wrapper(ctx: &CompletionContext) -> Option<impl Fn(&str) -> String> {
     let next_token_kind = {
-        let t = param.last_token()?.next_token()?;
+        let t = ctx.token.next_token()?;
         let t = algo::skip_whitespace_token(t, Direction::Next)?;
         t.kind()
     };
     let prev_token_kind = {
-        let t = param.first_token()?.prev_token()?;
+        let t = ctx.previous_token.clone()?;
         let t = algo::skip_whitespace_token(t, Direction::Prev)?;
         t.kind()
     };
@@ -183,9 +182,5 @@ fn comma_wrapper(ctx: &CompletionContext) -> Option<(impl Fn(&str) -> String, Te
         matches!(prev_token_kind, SyntaxKind::COMMA | SyntaxKind::L_PAREN | SyntaxKind::PIPE);
     let leading = if has_leading_comma { "" } else { ", " };
 
-    Some((
-        move |label: &_| (format!("{}{}{}", leading, label, trailing)),
-        param.text_range(),
-        format!("{}{}", leading, param.text()),
-    ))
+    Some(move |param: &_| format!("{}{}{}", leading, param, trailing))
 }
diff --git a/crates/ide_completion/src/completions/lifetime.rs b/crates/ide_completion/src/completions/lifetime.rs
index 4fffd1aa0c..66f8723912 100644
--- a/crates/ide_completion/src/completions/lifetime.rs
+++ b/crates/ide_completion/src/completions/lifetime.rs
@@ -22,8 +22,8 @@ pub(crate) fn complete_lifetime(acc: &mut Completions, ctx: &CompletionContext)
         Some(LifetimeContext::LifetimeParam { is_decl: false, param }) => Some(param),
         _ => return,
     };
-    let param_lifetime = match (&ctx.name_syntax, lp.and_then(|lp| lp.lifetime())) {
-        (Some(ast::NameLike::Lifetime(lt)), Some(lp)) if lp == lt.clone() => return,
+    let param_lifetime = match (ctx.lifetime(), lp.and_then(|lp| lp.lifetime())) {
+        (Some(lt), Some(lp)) if lp == lt.clone() => return,
         (Some(_), Some(lp)) => Some(lp),
         _ => None,
     };
diff --git a/crates/ide_completion/src/completions/use_.rs b/crates/ide_completion/src/completions/use_.rs
index 94df46efb0..07f14c8735 100644
--- a/crates/ide_completion/src/completions/use_.rs
+++ b/crates/ide_completion/src/completions/use_.rs
@@ -11,12 +11,9 @@ use crate::{
 };
 
 pub(crate) fn complete_use_tree(acc: &mut Completions, ctx: &CompletionContext) {
-    let (is_absolute_path, qualifier) = match ctx.path_context {
+    let (&is_absolute_path, qualifier) = match &ctx.path_context {
         Some(PathCompletionCtx {
-            kind: Some(PathKind::Use),
-            is_absolute_path,
-            ref qualifier,
-            ..
+            kind: Some(PathKind::Use), is_absolute_path, qualifier, ..
         }) => (is_absolute_path, qualifier),
         _ => return,
     };
@@ -45,13 +42,9 @@ pub(crate) fn complete_use_tree(acc: &mut Completions, ctx: &CompletionContext)
             if let Some(list) = ctx.token.ancestors().find_map(ast::UseTreeList::cast) {
                 let use_tree = list.parent_use_tree();
                 if use_tree.path().as_ref() == Some(path) {
-                    for tree in list.use_trees() {
-                        if tree.is_simple_path() {
-                            if let Some(name) =
-                                tree.path().and_then(|path| path.as_single_name_ref())
-                            {
-                                already_imported_names.insert(name.to_string());
-                            }
+                    for tree in list.use_trees().filter(|tree| tree.is_simple_path()) {
+                        if let Some(name) = tree.path().and_then(|path| path.as_single_name_ref()) {
+                            already_imported_names.insert(name.to_string());
                         }
                     }
                 }
@@ -62,14 +55,14 @@ pub(crate) fn complete_use_tree(acc: &mut Completions, ctx: &CompletionContext)
                     let module_scope = module.scope(ctx.db, Some(ctx.module));
                     let unknown_is_current = |name: &hir::Name| {
                         matches!(
-                            ctx.name_syntax.as_ref(),
-                            Some(ast::NameLike::NameRef(name_ref))
-                                if name_ref.syntax().text() == name.to_smol_str().as_str()
+                            ctx.name_ref(),
+                            Some(name_ref) if name_ref.syntax().text() == name.to_smol_str().as_str()
                         )
                     };
                     for (name, def) in module_scope {
-                        let is_name_already_imported =
-                            already_imported_names.contains(name.as_text().unwrap().as_str());
+                        let is_name_already_imported = name
+                            .as_text()
+                            .map_or(false, |text| already_imported_names.contains(text.as_str()));
 
                         let add_resolution = match def {
                             ScopeDef::Unknown if unknown_is_current(&name) => {
diff --git a/crates/ide_completion/src/completions/vis.rs b/crates/ide_completion/src/completions/vis.rs
index 338e003437..7315a488b8 100644
--- a/crates/ide_completion/src/completions/vis.rs
+++ b/crates/ide_completion/src/completions/vis.rs
@@ -8,11 +8,11 @@ use crate::{
 };
 
 pub(crate) fn complete_vis(acc: &mut Completions, ctx: &CompletionContext) {
-    let (is_absolute_path, qualifier, has_in_token) = match ctx.path_context {
+    let (&is_absolute_path, qualifier, &has_in_token) = match &ctx.path_context {
         Some(PathCompletionCtx {
             kind: Some(PathKind::Vis { has_in_token }),
             is_absolute_path,
-            ref qualifier,
+            qualifier,
             ..
         }) => (is_absolute_path, qualifier, has_in_token),
         _ => return,
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index 3ba02d78b5..a98e10a226 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -50,6 +50,7 @@ pub(super) enum PathKind {
     Type,
     Attr { kind: AttrKind, annotated_item_kind: Option<SyntaxKind> },
     Derive,
+    // This should be removed in favor of `has_macro_bang` in PathCompletionContext
     Mac,
     Pat,
     Vis { has_in_token: bool },
@@ -196,6 +197,14 @@ impl<'a> CompletionContext<'a> {
         }
     }
 
+    pub(crate) fn name_ref(&self) -> Option<&ast::NameRef> {
+        self.name_syntax.as_ref().and_then(ast::NameLike::as_name_ref)
+    }
+
+    pub(crate) fn lifetime(&self) -> Option<&ast::Lifetime> {
+        self.name_syntax.as_ref().and_then(ast::NameLike::as_lifetime)
+    }
+
     pub(crate) fn previous_token_is(&self, kind: SyntaxKind) -> bool {
         self.previous_token.as_ref().map_or(false, |tok| tok.kind() == kind)
     }
diff --git a/crates/ide_completion/src/render/function.rs b/crates/ide_completion/src/render/function.rs
index bd6833567c..9e5f91db39 100644
--- a/crates/ide_completion/src/render/function.rs
+++ b/crates/ide_completion/src/render/function.rs
@@ -562,90 +562,6 @@ fn qux(Foo { bar }: Foo) {
 fn main() {
   qux(${1:foo})$0
 }
-"#,
-        );
-    }
-
-    #[test]
-    fn complete_fn_param() {
-        // has mut kw
-        check_edit(
-            "mut ba",
-            r#"
-fn f(foo: (), mut bar: u32) {}
-fn g(foo: (), mut ba$0)
-"#,
-            r#"
-fn f(foo: (), mut bar: u32) {}
-fn g(foo: (), mut bar: u32)
-"#,
-        );
-
-        // has type param
-        check_edit(
-            "mut ba: u32",
-            r#"
-fn g(foo: (), mut ba$0: u32)
-fn f(foo: (), mut bar: u32) {}
-"#,
-            r#"
-fn g(foo: (), mut bar: u32)
-fn f(foo: (), mut bar: u32) {}
-"#,
-        );
-    }
-
-    #[test]
-    fn complete_fn_mut_param_add_comma() {
-        // add leading and trailing comma
-        check_edit(
-            ", mut ba",
-            r#"
-fn f(foo: (), mut bar: u32) {}
-fn g(foo: ()mut ba$0 baz: ())
-"#,
-            r#"
-fn f(foo: (), mut bar: u32) {}
-fn g(foo: (), mut bar: u32, baz: ())
-"#,
-        );
-    }
-
-    #[test]
-    fn complete_fn_mut_param_has_attribute() {
-        check_edit(
-            "mut ba",
-            r#"
-fn f(foo: (), #[baz = "qux"] mut bar: u32) {}
-fn g(foo: (), mut ba$0)
-"#,
-            r#"
-fn f(foo: (), #[baz = "qux"] mut bar: u32) {}
-fn g(foo: (), #[baz = "qux"] mut bar: u32)
-"#,
-        );
-
-        check_edit(
-            r#"#[baz = "qux"] mut ba"#,
-            r#"
-fn f(foo: (), #[baz = "qux"] mut bar: u32) {}
-fn g(foo: (), #[baz = "qux"] mut ba$0)
-"#,
-            r#"
-fn f(foo: (), #[baz = "qux"] mut bar: u32) {}
-fn g(foo: (), #[baz = "qux"] mut bar: u32)
-"#,
-        );
-
-        check_edit(
-            r#", #[baz = "qux"] mut ba"#,
-            r#"
-fn f(foo: (), #[baz = "qux"] mut bar: u32) {}
-fn g(foo: ()#[baz = "qux"] mut ba$0)
-"#,
-            r#"
-fn f(foo: (), #[baz = "qux"] mut bar: u32) {}
-fn g(foo: (), #[baz = "qux"] mut bar: u32)
 "#,
         );
     }
diff --git a/crates/ide_db/src/assists.rs b/crates/ide_db/src/assists.rs
index da23763dc2..be5f063f0f 100644
--- a/crates/ide_db/src/assists.rs
+++ b/crates/ide_db/src/assists.rs
@@ -29,7 +29,6 @@ pub struct Assist {
     /// cumbersome, especially if you want to embed an assist into another data
     /// structure, such as a diagnostic.
     pub source_change: Option<SourceChange>,
-    pub trigger_signature_help: bool,
 }
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
diff --git a/crates/ide_diagnostics/src/handlers/unresolved_module.rs b/crates/ide_diagnostics/src/handlers/unresolved_module.rs
index b8f2a9e94a..587a3ee26d 100644
--- a/crates/ide_diagnostics/src/handlers/unresolved_module.rs
+++ b/crates/ide_diagnostics/src/handlers/unresolved_module.rs
@@ -117,7 +117,6 @@ mod baz {}
                                             is_snippet: false,
                                         },
                                     ),
-                                    trigger_signature_help: false,
                                 },
                                 Assist {
                                     id: AssistId(
@@ -144,7 +143,6 @@ mod baz {}
                                             is_snippet: false,
                                         },
                                     ),
-                                    trigger_signature_help: false,
                                 },
                             ],
                         ),
diff --git a/crates/ide_diagnostics/src/lib.rs b/crates/ide_diagnostics/src/lib.rs
index b04da2e092..13ac0a2450 100644
--- a/crates/ide_diagnostics/src/lib.rs
+++ b/crates/ide_diagnostics/src/lib.rs
@@ -238,6 +238,5 @@ fn unresolved_fix(id: &'static str, label: &str, target: TextRange) -> Assist {
         group: None,
         target,
         source_change: None,
-        trigger_signature_help: false,
     }
 }
diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs
index 93255705be..1330a86950 100644
--- a/crates/project_model/src/workspace.rs
+++ b/crates/project_model/src/workspace.rs
@@ -759,9 +759,7 @@ fn handle_rustc_crates(
 
             let overrides = match override_cfg {
                 CfgOverrides::Wildcard(cfg_diff) => Some(cfg_diff),
-                CfgOverrides::Selective(cfg_overrides) => {
-                    cfg_overrides.get(&rustc_workspace[pkg].name)
-                }
+                CfgOverrides::Selective(cfg_overrides) => cfg_overrides.get(&cargo[pkg].name),
             };
 
             if let Some(overrides) = overrides {
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index df61ba8eec..15ae0e6480 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -77,13 +77,9 @@ fn try_main() -> Result<()> {
                 println!("{}", flags::RustAnalyzer::HELP);
                 return Ok(());
             }
-            with_extra_thread("rust-analyzer server thread", run_server)?;
-        }
-        flags::RustAnalyzerCmd::ProcMacro(flags::ProcMacro) => {
-            with_extra_thread("rust-analyzer proc-macro expander", || {
-                proc_macro_srv::cli::run().map_err(Into::into)
-            })?;
+            run_server()?
         }
+        flags::RustAnalyzerCmd::ProcMacro(flags::ProcMacro) => proc_macro_srv::cli::run()?,
         flags::RustAnalyzerCmd::Parse(cmd) => cmd.run()?,
         flags::RustAnalyzerCmd::Symbols(cmd) => cmd.run()?,
         flags::RustAnalyzerCmd::Highlight(cmd) => cmd.run()?,
@@ -132,23 +128,6 @@ fn setup_logging(log_file: Option<&Path>) -> Result<()> {
     Ok(())
 }
 
-const STACK_SIZE: usize = 1024 * 1024 * 8;
-
-/// Parts of rust-analyzer can use a lot of stack space, and some operating systems only give us
-/// 1 MB by default (eg. Windows), so this spawns a new thread with hopefully sufficient stack
-/// space.
-fn with_extra_thread(
-    thread_name: impl Into<String>,
-    f: impl FnOnce() -> Result<()> + Send + 'static,
-) -> Result<()> {
-    let handle =
-        std::thread::Builder::new().name(thread_name.into()).stack_size(STACK_SIZE).spawn(f)?;
-    match handle.join() {
-        Ok(res) => res,
-        Err(panic) => std::panic::resume_unwind(panic),
-    }
-}
-
 fn run_server() -> Result<()> {
     tracing::info!("server version {} will start", env!("REV"));
 
diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs
index e9a192cdfb..45e46c1a06 100644
--- a/crates/rust-analyzer/src/diagnostics/to_proto.rs
+++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs
@@ -204,7 +204,6 @@ fn map_rust_child_diagnostic(
                     }),
                     is_preferred: Some(true),
                     data: None,
-                    command: None,
                 },
             }),
         })
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index a1b71ab143..fb64eeea4f 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -1160,9 +1160,8 @@ pub(crate) fn handle_code_action_resolve(
         ))
         .into());
     }
-    let ca = to_proto::code_action(&snap, assist.clone(), None)?;
-    code_action.edit = ca.edit;
-    code_action.command = ca.command;
+    let edit = to_proto::code_action(&snap, assist.clone(), None)?.edit;
+    code_action.edit = edit;
     Ok(code_action)
 }
 
diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs
index 1cfaa13327..489a233a0a 100644
--- a/crates/rust-analyzer/src/lsp_ext.rs
+++ b/crates/rust-analyzer/src/lsp_ext.rs
@@ -311,8 +311,9 @@ pub struct CodeAction {
     pub group: Option<String>,
     #[serde(skip_serializing_if = "Option::is_none")]
     pub kind: Option<CodeActionKind>,
-    #[serde(skip_serializing_if = "Option::is_none")]
-    pub command: Option<lsp_types::Command>,
+    // We don't handle commands on the client-side
+    // #[serde(skip_serializing_if = "Option::is_none")]
+    // pub command: Option<lsp_types::Command>,
     #[serde(skip_serializing_if = "Option::is_none")]
     pub edit: Option<SnippetWorkspaceEdit>,
     #[serde(skip_serializing_if = "Option::is_none")]
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 57b0e93765..deea54cf7d 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -1018,13 +1018,7 @@ pub(crate) fn code_action(
         edit: None,
         is_preferred: None,
         data: None,
-        command: None,
     };
-
-    if assist.trigger_signature_help && snap.config.client_commands().trigger_parameter_hints {
-        res.command = Some(command::trigger_parameter_hints());
-    }
-
     match (assist.source_change, resolve_data) {
         (Some(it), _) => res.edit = Some(snippet_workspace_edit(snap, it)?),
         (None, Some((index, code_action_params))) => {
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index e1d4addb52..f2153ca921 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -426,6 +426,12 @@ impl NameLike {
             _ => None,
         }
     }
+    pub fn as_lifetime(&self) -> Option<&ast::Lifetime> {
+        match self {
+            NameLike::Lifetime(lifetime) => Some(lifetime),
+            _ => None,
+        }
+    }
 }
 
 impl ast::AstNode for NameLike {
diff --git a/docs/dev/README.md b/docs/dev/README.md
index b5a71fdae5..4a047e57a0 100644
--- a/docs/dev/README.md
+++ b/docs/dev/README.md
@@ -13,7 +13,7 @@ To learn more about how rust-analyzer works, see [./architecture.md](./architect
 It also explains the high-level layout of the source code.
 Do skim through that document.
 
-We also publish rustdoc docs to pages: https://rust-lang.github.io/rust-analyzer/ide/.
+We also publish rustdoc docs to pages: https://rust-analyzer.github.io/rust-analyzer/ide/.
 Note though, that the internal documentation is very incomplete.
 
 Various organizational and process issues are discussed in this document.
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md
index 2e1cee8955..46193a6ff3 100644
--- a/docs/dev/lsp-extensions.md
+++ b/docs/dev/lsp-extensions.md
@@ -1,5 +1,5 @@
 <!---
-lsp_ext.rs hash: 7a34bc3f38e2a7d8
+lsp_ext.rs hash: 326ad62235135223
 
 If you need to change the above hash to make the test pass, please check if you
 need to adjust this doc as well and ping this issue:
diff --git a/docs/dev/syntax.md b/docs/dev/syntax.md
index 863808e083..4f45aa321b 100644
--- a/docs/dev/syntax.md
+++ b/docs/dev/syntax.md
@@ -220,7 +220,7 @@ type SyntaxNode = Arc<SyntaxData>;
 struct SyntaxData {
     offset: usize,
     parent: Option<SyntaxNode>,
-    green: Arc<GreenNode>,
+    green: Arc<GreeNode>,
 }
 
 impl SyntaxNode {
@@ -302,7 +302,7 @@ type SyntaxNode = Arc<SyntaxData>;
 struct SyntaxData {
     offset: usize,
     parent: Option<SyntaxNode>,
-    green: Arc<GreenNode>,
+    green: Arc<GreeNode>,
     children: Vec<OnceCell<SyntaxNode>>,
 }
 ```
diff --git a/editors/code/language-configuration.json b/editors/code/language-configuration.json
index cf7b20eb79..2d772952a8 100644
--- a/editors/code/language-configuration.json
+++ b/editors/code/language-configuration.json
@@ -6,7 +6,8 @@
     "brackets": [
         ["{", "}"],
         ["[", "]"],
-        ["(", ")"]
+        ["(", ")"],
+        ["<", ">"]
     ],
     "colorizedBracketPairs": [
 		["{", "}"],
diff --git a/editors/code/package.json b/editors/code/package.json
index cd0ad92d9a..60c827e31a 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -293,6 +293,11 @@
                     "default": null,
                     "markdownDescription": "Environment variables passed to the runnable launched using `Test` or `Debug` lens or `rust-analyzer.run` command."
                 },
+                "rust-analyzer.inlayHints.enable": {
+                    "type": "boolean",
+                    "default": true,
+                    "description": "Whether to show inlay hints."
+                },
                 "rust-analyzer.server.path": {
                     "type": [
                         "null",
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts
index 1e89938c05..18f5b3aa10 100644
--- a/editors/code/src/commands.ts
+++ b/editors/code/src/commands.ts
@@ -300,9 +300,10 @@ export function serverVersion(ctx: Ctx): Cmd {
 
 export function toggleInlayHints(_ctx: Ctx): Cmd {
     return async () => {
-        const config = vscode.workspace.getConfiguration("editor.inlayHints", { languageId: "rust" });
+        const scope = vscode.ConfigurationTarget.Global;
+        const config = vscode.workspace.getConfiguration("editor.inlayHints");
         const value = !config.get("enabled");
-        await config.update('enabled', value, vscode.ConfigurationTarget.Global);
+        await config.update('enabled', value, scope);
     };
 }
 
@@ -734,9 +735,6 @@ export function resolveCodeAction(ctx: Ctx): Cmd {
         const fileSystemEdit = await client.protocol2CodeConverter.asWorkspaceEdit(lcFileSystemEdit);
         await vscode.workspace.applyEdit(fileSystemEdit);
         await applySnippetWorkspaceEdit(edit);
-        if (item.command != null) {
-            await vscode.commands.executeCommand(item.command.command, item.command.arguments);
-        }
     };
 }
 
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index 7591865390..0451e4c3d6 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -1,5 +1,4 @@
 import * as vscode from 'vscode';
-import * as lc from 'vscode-languageclient/node';
 import * as os from "os";
 
 import * as commands from './commands';
@@ -15,20 +14,16 @@ let ctx: Ctx | undefined;
 
 const RUST_PROJECT_CONTEXT_NAME = "inRustProject";
 
-export interface RustAnalyzerExtensionApi {
-    client: lc.LanguageClient;
-}
-
-export async function activate(context: vscode.ExtensionContext): Promise<RustAnalyzerExtensionApi> {
+export async function activate(context: vscode.ExtensionContext) {
     // VS Code doesn't show a notification when an extension fails to activate
     // so we do it ourselves.
-    return await tryActivate(context).catch(err => {
+    await tryActivate(context).catch(err => {
         void vscode.window.showErrorMessage(`Cannot activate rust-analyzer: ${err.message}`);
         throw err;
     });
 }
 
-async function tryActivate(context: vscode.ExtensionContext): Promise<RustAnalyzerExtensionApi> {
+async function tryActivate(context: vscode.ExtensionContext) {
     const config = new Config(context);
     const state = new PersistentState(context.globalState);
     const serverPath = await bootstrap(context, config, state).catch(err => {
@@ -67,10 +62,6 @@ async function tryActivate(context: vscode.ExtensionContext): Promise<RustAnalyz
         null,
         ctx.subscriptions,
     );
-
-    return {
-        client: ctx.client
-    };
 }
 
 async function initCommonContext(context: vscode.ExtensionContext, ctx: Ctx) {
diff --git a/triagebot.toml b/triagebot.toml
deleted file mode 100644
index fa0824ac53..0000000000
--- a/triagebot.toml
+++ /dev/null
@@ -1,1 +0,0 @@
-[assign]
diff --git a/xtask/src/release/changelog.rs b/xtask/src/release/changelog.rs
index 2647f7794f..ceef9fac2d 100644
--- a/xtask/src/release/changelog.rs
+++ b/xtask/src/release/changelog.rs
@@ -11,53 +11,56 @@ pub(crate) fn get_changelog(
     prev_tag: &str,
     today: &str,
 ) -> anyhow::Result<String> {
-    let token = match env::var("GITHUB_TOKEN") {
-        Ok(token) => token,
-        Err(_) => bail!("Please obtain a personal access token from https://github.com/settings/tokens and set the `GITHUB_TOKEN` environment variable."),
-    };
-
-    let git_log = cmd!(sh, "git log {prev_tag}..HEAD --reverse").read()?;
+    let git_log = cmd!(sh, "git log {prev_tag}..HEAD --merges --reverse").read()?;
     let mut features = String::new();
     let mut fixes = String::new();
     let mut internal = String::new();
     let mut others = String::new();
     for line in git_log.lines() {
         let line = line.trim_start();
-        if let Some(pr_num) = parse_pr_number(&line) {
-            let accept = "Accept: application/vnd.github.v3+json";
-            let authorization = format!("Authorization: token {}", token);
-            let pr_url = "https://api.github.com/repos/rust-lang/rust-analyzer/issues";
-
-            // we don't use an HTTPS client or JSON parser to keep the build times low
-            let pr = pr_num.to_string();
-            let pr_json =
-                cmd!(sh, "curl -s -H {accept} -H {authorization} {pr_url}/{pr}").read()?;
-            let pr_title = cmd!(sh, "jq .title").stdin(&pr_json).read()?;
-            let pr_title = unescape(&pr_title[1..pr_title.len() - 1]);
-            let pr_comment = cmd!(sh, "jq .body").stdin(pr_json).read()?;
-
-            let comments_json =
-                cmd!(sh, "curl -s -H {accept} -H {authorization} {pr_url}/{pr}/comments").read()?;
-            let pr_comments = cmd!(sh, "jq .[].body").stdin(comments_json).read()?;
-
-            let l = iter::once(pr_comment.as_str())
-                .chain(pr_comments.lines())
-                .rev()
-                .find_map(|it| {
-                    let it = unescape(&it[1..it.len() - 1]);
-                    it.lines().find_map(parse_changelog_line)
-                })
-                .into_iter()
-                .next()
-                .unwrap_or_else(|| parse_title_line(&pr_title));
-            let s = match l.kind {
-                PrKind::Feature => &mut features,
-                PrKind::Fix => &mut fixes,
-                PrKind::Internal => &mut internal,
-                PrKind::Other => &mut others,
-                PrKind::Skip => continue,
-            };
-            writeln!(s, "* pr:{}[] {}", pr_num, l.message.as_deref().unwrap_or(&pr_title)).unwrap();
+        if let Some(p) = line.find(':') {
+            let pr = &line[..p];
+            if let Ok(pr_num) = pr.parse::<u32>() {
+                let accept = "Accept: application/vnd.github.v3+json";
+                let token = match env::var("GITHUB_TOKEN") {
+                    Ok(token) => token,
+                    Err(_) => bail!("Please obtain a personal access token from https://github.com/settings/tokens and set the `GITHUB_TOKEN` environment variable."),
+                };
+                let authorization = format!("Authorization: token {}", token);
+                let pr_url = "https://api.github.com/repos/rust-analyzer/rust-analyzer/issues";
+
+                // we don't use an HTTPS client or JSON parser to keep the build times low
+                let pr_json =
+                    cmd!(sh, "curl -s -H {accept} -H {authorization} {pr_url}/{pr}").read()?;
+                let pr_title = cmd!(sh, "jq .title").stdin(&pr_json).read()?;
+                let pr_title = unescape(&pr_title[1..pr_title.len() - 1]);
+                let pr_comment = cmd!(sh, "jq .body").stdin(pr_json).read()?;
+
+                let comments_json =
+                    cmd!(sh, "curl -s -H {accept} -H {authorization} {pr_url}/{pr}/comments")
+                        .read()?;
+                let pr_comments = cmd!(sh, "jq .[].body").stdin(comments_json).read()?;
+
+                let l = iter::once(pr_comment.as_str())
+                    .chain(pr_comments.lines())
+                    .rev()
+                    .find_map(|it| {
+                        let it = unescape(&it[1..it.len() - 1]);
+                        it.lines().find_map(parse_changelog_line)
+                    })
+                    .into_iter()
+                    .next()
+                    .unwrap_or_else(|| parse_title_line(&pr_title));
+                let s = match l.kind {
+                    PrKind::Feature => &mut features,
+                    PrKind::Fix => &mut fixes,
+                    PrKind::Internal => &mut internal,
+                    PrKind::Other => &mut others,
+                    PrKind::Skip => continue,
+                };
+                writeln!(s, "* pr:{}[] {}", pr_num, l.message.as_deref().unwrap_or(&pr_title))
+                    .unwrap();
+            }
         }
     }
 
@@ -70,6 +73,11 @@ pub(crate) fn get_changelog(
 Commit: commit:{}[] +
 Release: release:{}[]
 
+== Sponsors
+
+**Become a sponsor:** On https://opencollective.com/rust-analyzer/[OpenCollective] or
+https://github.com/sponsors/rust-analyzer[GitHub Sponsors].
+
 == New Features
 
 {}
@@ -109,24 +117,6 @@ fn unescape(s: &str) -> String {
     s.replace(r#"\""#, "").replace(r#"\n"#, "\n").replace(r#"\r"#, "")
 }
 
-fn parse_pr_number(s: &str) -> Option<u32> {
-    const BORS_PREFIX: &str = "Merge #";
-    const HOMU_PREFIX: &str = "Auto merge of #";
-    if s.starts_with(BORS_PREFIX) {
-        let s = &s[BORS_PREFIX.len()..];
-        s.parse().ok()
-    } else if s.starts_with(HOMU_PREFIX) {
-        let s = &s[HOMU_PREFIX.len()..];
-        if let Some(space) = s.find(' ') {
-            s[..space].parse().ok()
-        } else {
-            None
-        }
-    } else {
-        None
-    }
-}
-
 fn parse_changelog_line(s: &str) -> Option<PrInfo> {
     let parts = s.splitn(3, ' ').collect::<Vec<_>>();
     if parts.len() < 2 || parts[0] != "changelog" {


Test patch:
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs
index ef27667ffa..c3c934c468 100644
--- a/crates/hir_ty/src/tests/regression.rs
+++ b/crates/hir_ty/src/tests/regression.rs
@@ -1470,22 +1470,6 @@ fn regression_11688_3() {
     );
 }
 
-#[test]
-fn regression_11688_4() {
-    check_types(
-        r#"
-        trait Bar<const C: usize> {
-            fn baz(&self) -> [i32; C];
-        }
-
-        fn foo(x: &dyn Bar<2>) {
-            x.baz();
-          //^^^^^^^ [i32; 2]
-        }
-        "#,
-    )
-}
-
 #[test]
 fn gat_crash_1() {
     cov_mark::check!(ignore_gats);
diff --git a/crates/ide_assists/src/tests.rs b/crates/ide_assists/src/tests.rs
index 6b57f9962c..b3a0bd2773 100644
--- a/crates/ide_assists/src/tests.rs
+++ b/crates/ide_assists/src/tests.rs
@@ -341,7 +341,6 @@ pub fn test_some_range(a: int) -> bool {
                 group: None,
                 target: 59..60,
                 source_change: None,
-                trigger_signature_help: false,
             }
         "#]]
         .assert_debug_eq(&extract_into_variable_assist);
@@ -357,7 +356,6 @@ pub fn test_some_range(a: int) -> bool {
                 group: None,
                 target: 59..60,
                 source_change: None,
-                trigger_signature_help: false,
             }
         "#]]
         .assert_debug_eq(&extract_into_function_assist);
@@ -387,7 +385,6 @@ pub fn test_some_range(a: int) -> bool {
                 group: None,
                 target: 59..60,
                 source_change: None,
-                trigger_signature_help: false,
             }
         "#]]
         .assert_debug_eq(&extract_into_variable_assist);
@@ -403,7 +400,6 @@ pub fn test_some_range(a: int) -> bool {
                 group: None,
                 target: 59..60,
                 source_change: None,
-                trigger_signature_help: false,
             }
         "#]]
         .assert_debug_eq(&extract_into_function_assist);
@@ -454,7 +450,6 @@ pub fn test_some_range(a: int) -> bool {
                         is_snippet: true,
                     },
                 ),
-                trigger_signature_help: false,
             }
         "#]]
         .assert_debug_eq(&extract_into_variable_assist);
@@ -470,7 +465,6 @@ pub fn test_some_range(a: int) -> bool {
                 group: None,
                 target: 59..60,
                 source_change: None,
-                trigger_signature_help: false,
             }
         "#]]
         .assert_debug_eq(&extract_into_function_assist);
@@ -513,7 +507,6 @@ pub fn test_some_range(a: int) -> bool {
                         is_snippet: true,
                     },
                 ),
-                trigger_signature_help: false,
             }
         "#]]
         .assert_debug_eq(&extract_into_variable_assist);
@@ -550,7 +543,6 @@ pub fn test_some_range(a: int) -> bool {
                         is_snippet: true,
                     },
                 ),
-                trigger_signature_help: false,
             }
         "#]]
         .assert_debug_eq(&extract_into_function_assist);
diff --git a/crates/ide_completion/src/tests/fn_param.rs b/crates/ide_completion/src/tests/fn_param.rs
index 678c99aa7a..779ec0c3a7 100644
--- a/crates/ide_completion/src/tests/fn_param.rs
+++ b/crates/ide_completion/src/tests/fn_param.rs
@@ -232,16 +232,3 @@ fn bar(bar$0) {}
         "#]],
     )
 }
-
-#[test]
-fn completes_for_params_with_attributes() {
-    check(
-        r#"
-fn f(foo: (), #[baz = "qux"] mut bar: u32) {}
-fn g(foo: (), #[baz = "qux"] mut ba$0)
-"#,
-        expect![[r##"
-            bn #[baz = "qux"] mut bar: u32
-        "##]],
-    )
-}
diff --git a/crates/rust-analyzer/src/diagnostics/test_data/clippy_pass_by_ref.txt b/crates/rust-analyzer/src/diagnostics/test_data/clippy_pass_by_ref.txt
index 41c509452a..4610984acb 100644
--- a/crates/rust-analyzer/src/diagnostics/test_data/clippy_pass_by_ref.txt
+++ b/crates/rust-analyzer/src/diagnostics/test_data/clippy_pass_by_ref.txt
@@ -318,7 +318,6 @@
                             "quickfix",
                         ),
                     ),
-                    command: None,
                     edit: Some(
                         SnippetWorkspaceEdit {
                             changes: Some(
diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt
index 1c5c336223..46d44192c5 100644
--- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt
+++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt
@@ -165,7 +165,6 @@
                             "quickfix",
                         ),
                     ),
-                    command: None,
                     edit: Some(
                         SnippetWorkspaceEdit {
                             changes: Some(
diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt
index 3ab3412d97..b595487e8f 100644
--- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt
+++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt
@@ -165,7 +165,6 @@
                             "quickfix",
                         ),
                     ),
-                    command: None,
                     edit: Some(
                         SnippetWorkspaceEdit {
                             changes: Some(
diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt
index 0702420aa5..3ee50392a7 100644
--- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt
+++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt
@@ -165,7 +165,6 @@
                             "quickfix",
                         ),
                     ),
-                    command: None,
                     edit: Some(
                         SnippetWorkspaceEdit {
                             changes: Some(
diff --git a/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt b/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt
index 4365e450df..d7987f65ed 100644
--- a/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt
+++ b/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt
@@ -328,7 +328,6 @@
                             "quickfix",
                         ),
                     ),
-                    command: None,
                     edit: Some(
                         SnippetWorkspaceEdit {
                             changes: Some(