Repository: rust-analyzer/rust-analyzer
Pull request #10440 (2021-10-03 13:07:04)

Fix Clippy warnings and replace some `if let`s with `match`
I decided to try fixing a bunch of Clippy warnings. I am aware of this project’s opinion of Clippy (I have read both [rust-lang/clippy#5537](https://github.com/rust-lang/rust-clippy/issues/5537) and [rust-analyzer/rowan#57 (comment)](https://github.com/rust-analyzer/rowan/pull/57#discussion_r415676159)), so I totally understand if part of or the entirety of this PR is rejected. In particular, I can see how the semicolons and `if let` vs `match` commits provide comparatively little benefit when compared to the ensuing churn.

I tried to separate each kind of change into its own commit to make it easier to discard certain changes. I also only applied Clippy suggestions where I thought they provided a definite improvement to the code (apart from semicolons, which is IMO more of a formatting/consistency question than a linting question). In the end I accumulated a list of 28 Clippy lints I ignored entirely.

Sidenote: I should really have asked about this on Zulip before going through all 1,555 `if let`s in the codebase to decide which ones definitely look better as `match` :P


Patch:
diff --git a/crates/flycheck/src/lib.rs b/crates/flycheck/src/lib.rs
index 40dfe6f511..0661d776f1 100644
--- a/crates/flycheck/src/lib.rs
+++ b/crates/flycheck/src/lib.rs
@@ -179,7 +179,7 @@ impl FlycheckActor {
                         tracing::error!(
                             "Flycheck failed to run the following command: {:?}",
                             self.check_command()
-                        )
+                        );
                     }
                     self.progress(Progress::DidFinish(res));
                 }
@@ -253,14 +253,14 @@ impl FlycheckActor {
     }
 
     fn send(&self, check_task: Message) {
-        (self.sender)(check_task)
+        (self.sender)(check_task);
     }
 }
 
 struct CargoHandle {
     child: JodChild,
     #[allow(unused)]
-    thread: jod_thread::JoinHandle<io::Result<bool>>,
+    thread: jod_thread::JoinHandle<bool>,
     receiver: Receiver<CargoMessage>,
 }
 
@@ -279,7 +279,7 @@ impl CargoHandle {
         // It is okay to ignore the result, as it only errors if the process is already dead
         let _ = self.child.kill();
         let exit_status = self.child.wait()?;
-        let read_at_least_one_message = self.thread.join()?;
+        let read_at_least_one_message = self.thread.join();
         if !exit_status.success() && !read_at_least_one_message {
             // FIXME: Read the stderr to display the reason, see `read2()` reference in PR comment:
             // https://github.com/rust-analyzer/rust-analyzer/pull/3632#discussion_r395605298
@@ -304,7 +304,7 @@ impl CargoActor {
     fn new(child_stdout: process::ChildStdout, sender: Sender<CargoMessage>) -> CargoActor {
         CargoActor { child_stdout, sender }
     }
-    fn run(self) -> io::Result<bool> {
+    fn run(self) -> bool {
         // We manually read a line at a time, instead of using serde's
         // stream deserializers, because the deserializer cannot recover
         // from an error, resulting in it getting stuck, because we try to
@@ -334,20 +334,20 @@ impl CargoActor {
                     // Skip certain kinds of messages to only spend time on what's useful
                     JsonMessage::Cargo(message) => match message {
                         cargo_metadata::Message::CompilerArtifact(artifact) if !artifact.fresh => {
-                            self.sender.send(CargoMessage::CompilerArtifact(artifact)).unwrap()
+                            self.sender.send(CargoMessage::CompilerArtifact(artifact)).unwrap();
                         }
                         cargo_metadata::Message::CompilerMessage(msg) => {
-                            self.sender.send(CargoMessage::Diagnostic(msg.message)).unwrap()
+                            self.sender.send(CargoMessage::Diagnostic(msg.message)).unwrap();
                         }
                         _ => (),
                     },
                     JsonMessage::Rustc(message) => {
-                        self.sender.send(CargoMessage::Diagnostic(message)).unwrap()
+                        self.sender.send(CargoMessage::Diagnostic(message)).unwrap();
                     }
                 }
             }
         }
-        Ok(read_at_least_one_message)
+        read_at_least_one_message
     }
 }
 
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs
index a541cbd5e1..aa4f25a3b4 100644
--- a/crates/hir/src/display.rs
+++ b/crates/hir/src/display.rs
@@ -241,7 +241,7 @@ impl HirDisplay for TypeParam {
             return Ok(());
         }
 
-        let bounds = f.db.generic_predicates_for_param(self.id, None);
+        let bounds = f.db.generic_predicates_for_param(self.id);
         let substs = TyBuilder::type_params_subst(f.db, self.id.parent);
         let predicates: Vec<_> =
             bounds.iter().cloned().map(|b| b.substitute(&Interner, &substs)).collect();
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index a33c8ce65e..038c69bc73 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -1119,7 +1119,7 @@ impl DefWithBody {
                                 if let ast::Expr::RecordExpr(record_expr) =
                                     &source_ptr.value.to_node(&root)
                                 {
-                                    if let Some(_) = record_expr.record_expr_field_list() {
+                                    if record_expr.record_expr_field_list().is_some() {
                                         acc.push(
                                             MissingFields {
                                                 file: source_ptr.file_id,
@@ -1143,7 +1143,7 @@ impl DefWithBody {
                                 if let Some(expr) = source_ptr.value.as_ref().left() {
                                     let root = source_ptr.file_syntax(db.upcast());
                                     if let ast::Pat::RecordPat(record_pat) = expr.to_node(&root) {
-                                        if let Some(_) = record_pat.record_pat_field_list() {
+                                        if record_pat.record_pat_field_list().is_some() {
                                             acc.push(
                                                 MissingFields {
                                                     file: source_ptr.file_id,
@@ -2024,7 +2024,7 @@ impl TypeParam {
     }
 
     pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> {
-        db.generic_predicates_for_param(self.id, None)
+        db.generic_predicates_for_param(self.id)
             .iter()
             .filter_map(|pred| match &pred.skip_binders().skip_binders() {
                 hir_ty::WhereClause::Implemented(trait_ref) => {
@@ -2119,10 +2119,9 @@ impl Impl {
         };
 
         let fp = TyFingerprint::for_inherent_impl(&ty);
-        let fp = if let Some(fp) = fp {
-            fp
-        } else {
-            return Vec::new();
+        let fp = match fp {
+            Some(fp) => fp,
+            None => return Vec::new(),
         };
 
         let mut all = Vec::new();
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index 804d98ce38..4c1a3344ec 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -474,10 +474,9 @@ impl ExprCollector<'_> {
             }
             ast::Expr::PrefixExpr(e) => {
                 let expr = self.collect_expr_opt(e.expr());
-                if let Some(op) = e.op_kind() {
-                    self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr)
-                } else {
-                    self.alloc_expr(Expr::Missing, syntax_ptr)
+                match e.op_kind() {
+                    Some(op) => self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr),
+                    None => self.alloc_expr(Expr::Missing, syntax_ptr),
                 }
             }
             ast::Expr::ClosureExpr(e) => {
@@ -624,10 +623,9 @@ impl ExprCollector<'_> {
     }
 
     fn collect_expr_opt(&mut self, expr: Option<ast::Expr>) -> ExprId {
-        if let Some(expr) = expr {
-            self.collect_expr(expr)
-        } else {
-            self.missing_expr()
+        match expr {
+            Some(expr) => self.collect_expr(expr),
+            None => self.missing_expr(),
         }
     }
 
@@ -724,10 +722,9 @@ impl ExprCollector<'_> {
     }
 
     fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId {
-        if let Some(block) = expr {
-            self.collect_block(block)
-        } else {
-            self.missing_expr()
+        match expr {
+            Some(block) => self.collect_block(block),
+            None => self.missing_expr(),
         }
     }
 
@@ -890,10 +887,9 @@ impl ExprCollector<'_> {
     }
 
     fn collect_pat_opt(&mut self, pat: Option<ast::Pat>) -> PatId {
-        if let Some(pat) = pat {
-            self.collect_pat(pat)
-        } else {
-            self.missing_pat()
+        match pat {
+            Some(pat) => self.collect_pat(pat),
+            None => self.missing_pat(),
         }
     }
 
diff --git a/crates/hir_def/src/find_path.rs b/crates/hir_def/src/find_path.rs
index 08ffa8e53d..3251638c7a 100644
--- a/crates/hir_def/src/find_path.rs
+++ b/crates/hir_def/src/find_path.rs
@@ -209,10 +209,9 @@ fn find_path_inner(
             ) {
                 path.push_segment(name);
 
-                let new_path = if let Some(best_path) = best_path {
-                    select_best_path(best_path, path, prefer_no_std)
-                } else {
-                    path
+                let new_path = match best_path {
+                    Some(best_path) => select_best_path(best_path, path, prefer_no_std),
+                    None => path,
                 };
                 best_path_len = new_path.len();
                 best_path = Some(new_path);
@@ -243,10 +242,9 @@ fn find_path_inner(
         });
 
         for path in extern_paths {
-            let new_path = if let Some(best_path) = best_path {
-                select_best_path(best_path, path, prefer_no_std)
-            } else {
-                path
+            let new_path = match best_path {
+                Some(best_path) => select_best_path(best_path, path, prefer_no_std),
+                None => path,
             };
             best_path = Some(new_path);
         }
@@ -261,12 +259,11 @@ fn find_path_inner(
         }
     }
 
-    if let Some(prefix) = prefixed.map(PrefixKind::prefix) {
-        best_path.or_else(|| {
+    match prefixed.map(PrefixKind::prefix) {
+        Some(prefix) => best_path.or_else(|| {
             scope_name.map(|scope_name| ModPath::from_segments(prefix, vec![scope_name]))
-        })
-    } else {
-        best_path
+        }),
+        None => best_path,
     }
 }
 
@@ -346,15 +343,13 @@ fn find_local_import_locations(
 
         if let Some((name, vis)) = data.scope.name_of(item) {
             if vis.is_visible_from(db, from) {
-                let is_private = if let Visibility::Module(private_to) = vis {
-                    private_to.local_id == module.local_id
-                } else {
-                    false
+                let is_private = match vis {
+                    Visibility::Module(private_to) => private_to.local_id == module.local_id,
+                    Visibility::Public => false,
                 };
-                let is_original_def = if let Some(module_def_id) = item.as_module_def_id() {
-                    data.scope.declarations().any(|it| it == module_def_id)
-                } else {
-                    false
+                let is_original_def = match item.as_module_def_id() {
+                    Some(module_def_id) => data.scope.declarations().any(|it| it == module_def_id),
+                    None => false,
                 };
 
                 // Ignore private imports. these could be used if we are
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index 3900e7e97c..b7a5758a0a 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -475,10 +475,9 @@ macro_rules! mod_items {
                 }
 
                 fn id_from_mod_item(mod_item: ModItem) -> Option<FileItemTreeId<Self>> {
-                    if let ModItem::$typ(id) = mod_item {
-                        Some(id)
-                    } else {
-                        None
+                    match mod_item {
+                        ModItem::$typ(id) => Some(id),
+                        _ => None,
                     }
                 }
 
diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs
index 4fb81bde46..30f11cc694 100644
--- a/crates/hir_def/src/nameres/path_resolution.rs
+++ b/crates/hir_def/src/nameres/path_resolution.rs
@@ -400,13 +400,10 @@ impl DefMap {
         };
         let from_scope_or_builtin = match shadow {
             BuiltinShadowMode::Module => from_scope.or(from_builtin),
-            BuiltinShadowMode::Other => {
-                if let Some(ModuleDefId::ModuleId(_)) = from_scope.take_types() {
-                    from_builtin.or(from_scope)
-                } else {
-                    from_scope.or(from_builtin)
-                }
-            }
+            BuiltinShadowMode::Other => match from_scope.take_types() {
+                Some(ModuleDefId::ModuleId(_)) => from_builtin.or(from_scope),
+                Some(_) | None => from_scope.or(from_builtin),
+            },
         };
         let from_extern_prelude = self
             .extern_prelude
diff --git a/crates/hir_def/src/path/lower/lower_use.rs b/crates/hir_def/src/path/lower/lower_use.rs
index 0ee406f63a..6b777cfeff 100644
--- a/crates/hir_def/src/path/lower/lower_use.rs
+++ b/crates/hir_def/src/path/lower/lower_use.rs
@@ -18,10 +18,9 @@ pub(crate) fn convert_path(
     path: ast::Path,
     hygiene: &Hygiene,
 ) -> Option<ModPath> {
-    let prefix = if let Some(qual) = path.qualifier() {
-        Some(convert_path(db, prefix, qual, hygiene)?)
-    } else {
-        prefix
+    let prefix = match path.qualifier() {
+        Some(qual) => Some(convert_path(db, prefix, qual, hygiene)?),
+        None => prefix,
     };
 
     let segment = path.segment()?;
diff --git a/crates/hir_def/src/type_ref.rs b/crates/hir_def/src/type_ref.rs
index 9f33fd26e8..cfc69feccc 100644
--- a/crates/hir_def/src/type_ref.rs
+++ b/crates/hir_def/src/type_ref.rs
@@ -214,10 +214,9 @@ impl TypeRef {
     }
 
     pub(crate) fn from_ast_opt(ctx: &LowerCtx, node: Option<ast::Type>) -> Self {
-        if let Some(node) = node {
-            TypeRef::from_ast(ctx, node)
-        } else {
-            TypeRef::Error
+        match node {
+            Some(node) => TypeRef::from_ast(ctx, node),
+            None => TypeRef::Error,
         }
     }
 
diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs
index 9c844c6138..552603dce7 100644
--- a/crates/hir_expand/src/name.rs
+++ b/crates/hir_expand/src/name.rs
@@ -48,10 +48,9 @@ impl Name {
 
     /// Resolve a name from the text of token.
     fn resolve(raw_text: &str) -> Name {
-        if let Some(text) = raw_text.strip_prefix("r#") {
-            Name::new_text(SmolStr::new(text))
-        } else {
-            Name::new_text(raw_text.into())
+        match raw_text.strip_prefix("r#") {
+            Some(text) => Name::new_text(SmolStr::new(text)),
+            None => Name::new_text(raw_text.into()),
         }
     }
 
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index e3f008645c..4dc46a2cde 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -109,10 +109,9 @@ pub(crate) fn deref(
     ty: InEnvironment<&Canonical<Ty>>,
 ) -> Option<Canonical<Ty>> {
     let _p = profile::span("deref");
-    if let Some(derefed) = builtin_deref(&ty.goal.value) {
-        Some(Canonical { value: derefed, binders: ty.goal.binders.clone() })
-    } else {
-        deref_by_trait(db, krate, ty)
+    match builtin_deref(&ty.goal.value) {
+        Some(derefed) => Some(Canonical { value: derefed, binders: ty.goal.binders.clone() }),
+        None => deref_by_trait(db, krate, ty),
     }
 }
 
diff --git a/crates/hir_ty/src/chalk_ext.rs b/crates/hir_ty/src/chalk_ext.rs
index c29fbd688a..36c56820eb 100644
--- a/crates/hir_ty/src/chalk_ext.rs
+++ b/crates/hir_ty/src/chalk_ext.rs
@@ -104,10 +104,9 @@ impl TyExt for Ty {
     }
 
     fn as_fn_def(&self, db: &dyn HirDatabase) -> Option<FunctionId> {
-        if let Some(CallableDefId::FunctionId(func)) = self.callable_def(db) {
-            Some(func)
-        } else {
-            None
+        match self.callable_def(db) {
+            Some(CallableDefId::FunctionId(func)) => Some(func),
+            Some(CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_)) | None => None,
         }
     }
     fn as_reference(&self) -> Option<(&Ty, Lifetime, Mutability)> {
diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs
index 98a5849001..b9003c413b 100644
--- a/crates/hir_ty/src/db.rs
+++ b/crates/hir_ty/src/db.rs
@@ -61,7 +61,6 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
     fn generic_predicates_for_param(
         &self,
         param_id: TypeParamId,
-        assoc_name: Option<Name>,
     ) -> Arc<[Binders<QuantifiedWhereClause>]>;
 
     #[salsa::invoke(crate::lower::generic_predicates_query)]
diff --git a/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs b/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs
index 2fa456a035..f9439c706e 100644
--- a/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs
+++ b/crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs
@@ -105,10 +105,9 @@ impl IntRange {
 
     #[inline]
     fn from_range(lo: u128, hi: u128, scalar_ty: Scalar) -> IntRange {
-        if let Scalar::Bool = scalar_ty {
-            IntRange { range: lo..=hi }
-        } else {
-            unimplemented!()
+        match scalar_ty {
+            Scalar::Bool => IntRange { range: lo..=hi },
+            _ => unimplemented!(),
         }
     }
 
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 1ae718a36b..adce43aa07 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -167,10 +167,9 @@ impl<'a> HirFormatter<'a> {
     }
 
     pub fn should_truncate(&self) -> bool {
-        if let Some(max_size) = self.max_size {
-            self.curr_size >= max_size
-        } else {
-            false
+        match self.max_size {
+            Some(max_size) => self.curr_size >= max_size,
+            None => false,
         }
     }
 
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index b0306d9148..f5bc898a85 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -264,10 +264,9 @@ impl<'a> InferenceContext<'a> {
 
                 // collect explicitly written argument types
                 for arg_type in arg_types.iter() {
-                    let arg_ty = if let Some(type_ref) = arg_type {
-                        self.make_ty(type_ref)
-                    } else {
-                        self.table.new_type_var()
+                    let arg_ty = match arg_type {
+                        Some(type_ref) => self.make_ty(type_ref),
+                        None => self.table.new_type_var(),
                     };
                     sig_tys.push(arg_ty);
                 }
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index 957cd829aa..9aaf7db87b 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -204,10 +204,9 @@ impl<'a> InferenceContext<'a> {
                 } else {
                     BindingMode::convert(*mode)
                 };
-                let inner_ty = if let Some(subpat) = subpat {
-                    self.infer_pat(*subpat, &expected, default_bm)
-                } else {
-                    expected
+                let inner_ty = match subpat {
+                    Some(subpat) => self.infer_pat(*subpat, &expected, default_bm),
+                    None => expected,
                 };
                 let inner_ty = self.insert_type_vars_shallow(inner_ty);
 
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 4c1e758904..c40ef7f587 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -324,10 +324,9 @@ impl<'a> InferenceTable<'a> {
 
     /// Unify two types and register new trait goals that arise from that.
     pub(crate) fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
-        let result = if let Ok(r) = self.try_unify(ty1, ty2) {
-            r
-        } else {
-            return false;
+        let result = match self.try_unify(ty1, ty2) {
+            Ok(r) => r,
+            Err(_) => return false,
         };
         self.register_infer_ok(result);
         true
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index d5f3940149..df1eb1c961 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -30,7 +30,6 @@ use smallvec::SmallVec;
 use stdx::impl_from;
 use syntax::ast;
 
-use crate::all_super_traits;
 use crate::{
     consteval,
     db::HirDatabase,
@@ -369,10 +368,9 @@ impl<'a> TyLoweringContext<'a> {
                 Some((it, None)) => it,
                 _ => return None,
             };
-        if let TypeNs::GenericParam(param_id) = resolution {
-            Some(param_id)
-        } else {
-            None
+        match resolution {
+            TypeNs::GenericParam(param_id) => Some(param_id),
+            _ => None,
         }
     }
 
@@ -532,10 +530,9 @@ impl<'a> TyLoweringContext<'a> {
 
     fn select_associated_type(&self, res: Option<TypeNs>, segment: PathSegment<'_>) -> Ty {
         if let Some(res) = res {
-            let ty = named_associated_type_shorthand_candidates(
+            let ty = associated_type_shorthand_candidates(
                 self.db,
                 res,
-                Some(segment.name.clone()),
                 move |name, t, associated_ty| {
                     if name == segment.name {
                         let substs = match self.type_param_mode {
@@ -557,16 +554,16 @@ impl<'a> TyLoweringContext<'a> {
                         // associated_type_shorthand_candidates does not do that
                         let substs = substs.shifted_in_from(&Interner, self.in_binders);
                         // FIXME handle type parameters on the segment
-                        Some(
+                        return Some(
                             TyKind::Alias(AliasTy::Projection(ProjectionTy {
                                 associated_ty_id: to_assoc_type_id(associated_ty),
                                 substitution: substs,
                             }))
                             .intern(&Interner),
-                        )
-                    } else {
-                        None
+                        );
                     }
+
+                    None
                 },
             );
 
@@ -937,15 +934,6 @@ pub fn callable_item_sig(db: &dyn HirDatabase, def: CallableDefId) -> PolyFnSig
 pub fn associated_type_shorthand_candidates<R>(
     db: &dyn HirDatabase,
     res: TypeNs,
-    cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
-) -> Option<R> {
-    named_associated_type_shorthand_candidates(db, res, None, cb)
-}
-
-fn named_associated_type_shorthand_candidates<R>(
-    db: &dyn HirDatabase,
-    res: TypeNs,
-    assoc_name: Option<Name>,
     mut cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
 ) -> Option<R> {
     let mut search = |t| {
@@ -970,7 +958,7 @@ fn named_associated_type_shorthand_candidates<R>(
             db.impl_trait(impl_id)?.into_value_and_skipped_binders().0,
         ),
         TypeNs::GenericParam(param_id) => {
-            let predicates = db.generic_predicates_for_param(param_id, assoc_name);
+            let predicates = db.generic_predicates_for_param(param_id);
             let res = predicates.iter().find_map(|pred| match pred.skip_binders().skip_binders() {
                 // FIXME: how to correctly handle higher-ranked bounds here?
                 WhereClause::Implemented(tr) => search(
@@ -1033,7 +1021,6 @@ pub(crate) fn field_types_query(
 pub(crate) fn generic_predicates_for_param_query(
     db: &dyn HirDatabase,
     param_id: TypeParamId,
-    assoc_name: Option<Name>,
 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
     let resolver = param_id.parent.resolver(db.upcast());
     let ctx =
@@ -1043,46 +1030,13 @@ pub(crate) fn generic_predicates_for_param_query(
         .where_predicates_in_scope()
         // we have to filter out all other predicates *first*, before attempting to lower them
         .filter(|pred| match pred {
-            WherePredicate::ForLifetime { target, bound, .. }
-            | WherePredicate::TypeBound { target, bound, .. } => {
-                match target {
-                    WherePredicateTypeTarget::TypeRef(type_ref) => {
-                        if ctx.lower_ty_only_param(type_ref) != Some(param_id) {
-                            return false;
-                        }
-                    }
-                    WherePredicateTypeTarget::TypeParam(local_id) => {
-                        if *local_id != param_id.local_id {
-                            return false;
-                        }
-                    }
-                };
-
-                match &**bound {
-                    TypeBound::ForLifetime(_, path) | TypeBound::Path(path, _) => {
-                        // Only lower the bound if the trait could possibly define the associated
-                        // type we're looking for.
-
-                        let assoc_name = match &assoc_name {
-                            Some(it) => it,
-                            None => return true,
-                        };
-                        let tr = match resolver
-                            .resolve_path_in_type_ns_fully(db.upcast(), path.mod_path())
-                        {
-                            Some(TypeNs::TraitId(tr)) => tr,
-                            _ => return false,
-                        };
-
-                        all_super_traits(db.upcast(), tr).iter().any(|tr| {
-                            db.trait_data(*tr).items.iter().any(|(name, item)| {
-                                matches!(item, AssocItemId::TypeAliasId(_)) && name == assoc_name
-                            })
-                        })
-                    }
-                    TypeBound::Lifetime(_) | TypeBound::Error => false,
+            WherePredicate::ForLifetime { target, .. }
+            | WherePredicate::TypeBound { target, .. } => match target {
+                WherePredicateTypeTarget::TypeRef(type_ref) => {
+                    ctx.lower_ty_only_param(type_ref) == Some(param_id)
                 }
-            }
+                WherePredicateTypeTarget::TypeParam(local_id) => *local_id == param_id.local_id,
+            },
             WherePredicate::Lifetime { .. } => false,
         })
         .flat_map(|pred| ctx.lower_where_predicate(pred, true).map(|p| make_binders(&generics, p)))
@@ -1101,7 +1055,6 @@ pub(crate) fn generic_predicates_for_param_recover(
     _db: &dyn HirDatabase,
     _cycle: &[String],
     _param_id: &TypeParamId,
-    _assoc_name: &Option<Name>,
 ) -> Arc<[Binders<QuantifiedWhereClause>]> {
     Arc::new([])
 }
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index c88a8b6535..8e6ab8af0f 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -82,10 +82,9 @@ impl TyFingerprint {
             TyKind::Ref(_, _, ty) => return TyFingerprint::for_trait_impl(ty),
             TyKind::Tuple(_, subst) => {
                 let first_ty = subst.interned().get(0).map(|arg| arg.assert_ty_ref(&Interner));
-                if let Some(ty) = first_ty {
-                    return TyFingerprint::for_trait_impl(ty);
-                } else {
-                    TyFingerprint::Unit
+                match first_ty {
+                    Some(ty) => return TyFingerprint::for_trait_impl(ty),
+                    None => TyFingerprint::Unit,
                 }
             }
             TyKind::AssociatedType(_, _)
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs
index 07898f0088..14b8a726a8 100644
--- a/crates/hir_ty/src/utils.rs
+++ b/crates/hir_ty/src/utils.rs
@@ -79,7 +79,7 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr
         Some(p) => TypeParamId { parent: trait_ref.hir_trait_id().into(), local_id: p },
         None => return Vec::new(),
     };
-    db.generic_predicates_for_param(trait_self, None)
+    db.generic_predicates_for_param(trait_self)
         .iter()
         .filter_map(|pred| {
             pred.as_ref().filter_map(|pred| match pred.skip_binders() {
diff --git a/crates/ide/src/call_hierarchy.rs b/crates/ide/src/call_hierarchy.rs
index e83210f4f9..242b7b40e1 100644
--- a/crates/ide/src/call_hierarchy.rs
+++ b/crates/ide/src/call_hierarchy.rs
@@ -4,6 +4,7 @@ use indexmap::IndexMap;
 
 use hir::Semantics;
 use ide_db::{
+    call_info::FnCallNode,
     defs::{Definition, NameClass, NameRefClass},
     helpers::pick_best_token,
     search::FileReference,
@@ -100,27 +101,23 @@ pub(crate) fn outgoing_calls(db: &RootDatabase, position: FilePosition) -> Optio
             _ => None,
         })
         .flatten()
-        .filter_map(ast::CallableExpr::cast)
+        .filter_map(|node| FnCallNode::with_node_exact(&node))
         .filter_map(|call_node| {
-            let (nav_target, range) = match call_node {
-                ast::CallableExpr::Call(call) => {
-                    let expr = call.expr()?;
-                    let callable = sema.type_of_expr(&expr)?.original.as_callable(db)?;
+            let name_ref = call_node.name_ref()?;
+            let func_target = match call_node {
+                FnCallNode::CallExpr(expr) => {
+                    let callable = sema.type_of_expr(&expr.expr()?)?.original.as_callable(db)?;
                     match callable.kind() {
-                        hir::CallableKind::Function(it) => {
-                            let range = expr.syntax().text_range();
-                            it.try_to_nav(db).zip(Some(range))
-                        }
+                        hir::CallableKind::Function(it) => it.try_to_nav(db),
                         _ => None,
                     }
                 }
-                ast::CallableExpr::MethodCall(expr) => {
-                    let range = expr.name_ref()?.syntax().text_range();
+                FnCallNode::MethodCallExpr(expr) => {
                     let function = sema.resolve_method_call(&expr)?;
-                    function.try_to_nav(db).zip(Some(range))
+                    function.try_to_nav(db)
                 }
             }?;
-            Some((nav_target, range))
+            Some((func_target, name_ref.syntax().text_range()))
         })
         .for_each(|(nav, range)| calls.add(nav, range));
 
diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs
index 65c29f6805..01c1259fc5 100644
--- a/crates/ide/src/display/navigation_target.rs
+++ b/crates/ide/src/display/navigation_target.rs
@@ -292,10 +292,9 @@ impl TryToNav for hir::Impl {
     fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
         let src = self.source(db)?;
         let derive_attr = self.is_builtin_derive(db);
-        let frange = if let Some(item) = &derive_attr {
-            item.syntax().original_file_range(db)
-        } else {
-            src.syntax().original_file_range(db)
+        let frange = match &derive_attr {
+            Some(item) => item.syntax().original_file_range(db),
+            None => src.syntax().original_file_range(db),
         };
         let focus_range = if derive_attr.is_some() {
             None
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 3dcb510ab0..401feffff4 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -2,7 +2,6 @@ use either::Either;
 use hir::{known, Callable, HasVisibility, HirDisplay, Semantics, TypeInfo};
 use ide_db::RootDatabase;
 use ide_db::{base_db::FileRange, helpers::FamousDefs};
-use itertools::Itertools;
 use stdx::to_lower_snake_case;
 use syntax::{
     ast::{self, AstNode, HasArgList, HasName},
@@ -199,95 +198,28 @@ fn get_bind_pat_hints(
 
     let descended = sema.descend_node_into_attributes(pat.clone()).pop();
     let desc_pat = descended.as_ref().unwrap_or(pat);
+    let krate = sema.scope(desc_pat.syntax()).module().map(|it| it.krate());
+    let famous_defs = FamousDefs(sema, krate);
+
     let ty = sema.type_of_pat(&desc_pat.clone().into())?.original;
 
     if should_not_display_type_hint(sema, &pat, &ty) {
         return None;
     }
 
-    let krate = sema.scope(desc_pat.syntax()).module().map(|it| it.krate());
-    let famous_defs = FamousDefs(sema, krate);
-    let label = hint_iterator(sema, &famous_defs, config, &ty);
-
-    let label = match label {
-        Some(label) => label,
-        None => {
-            let ty_name = ty.display_truncated(sema.db, config.max_length).to_string();
-            if is_named_constructor(sema, pat, &ty_name).is_some() {
-                return None;
-            }
-            ty_name.into()
-        }
-    };
-
     acc.push(InlayHint {
         range: match pat.name() {
             Some(name) => name.syntax().text_range(),
             None => pat.syntax().text_range(),
         },
         kind: InlayKind::TypeHint,
-        label,
+        label: hint_iterator(sema, &famous_defs, config, &ty)
+            .unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string().into()),
     });
 
     Some(())
 }
 
-fn is_named_constructor(
-    sema: &Semantics<RootDatabase>,
-    pat: &ast::IdentPat,
-    ty_name: &str,
-) -> Option<()> {
-    let let_node = pat.syntax().parent()?;
-    let expr = match_ast! {
-        match let_node {
-            ast::LetStmt(it) => it.initializer(),
-            ast::Condition(it) => it.expr(),
-            _ => None,
-        }
-    }?;
-
-    let expr = sema.descend_node_into_attributes(expr.clone()).pop().unwrap_or(expr);
-    // unwrap postfix expressions
-    let expr = match expr {
-        ast::Expr::TryExpr(it) => it.expr(),
-        ast::Expr::AwaitExpr(it) => it.expr(),
-        expr => Some(expr),
-    }?;
-    let expr = match expr {
-        ast::Expr::CallExpr(call) => match call.expr()? {
-            ast::Expr::PathExpr(p) => p,
-            _ => return None,
-        },
-        _ => return None,
-    };
-    let path = expr.path()?;
-
-    // Check for tuple-struct or tuple-variant in which case we can check the last segment
-    let callable = sema.type_of_expr(&ast::Expr::PathExpr(expr))?.original.as_callable(sema.db);
-    let callable_kind = callable.map(|it| it.kind());
-    if let Some(hir::CallableKind::TupleStruct(_) | hir::CallableKind::TupleEnumVariant(_)) =
-        callable_kind
-    {
-        if let Some(ctor) = path.segment() {
-            return (&ctor.to_string() == ty_name).then(|| ());
-        }
-    }
-
-    // otherwise use the qualifying segment as the constructor name
-    let qual_seg = path.qualifier()?.segment()?;
-    let ctor_name = match qual_seg.kind()? {
-        ast::PathSegmentKind::Name(name_ref) => {
-            match qual_seg.generic_arg_list().map(|it| it.generic_args()) {
-                Some(generics) => format!("{}<{}>", name_ref, generics.format(", ")),
-                None => name_ref.to_string(),
-            }
-        }
-        ast::PathSegmentKind::Type { type_ref: Some(ty), trait_ref: None } => ty.to_string(),
-        _ => return None,
-    };
-    (&ctor_name == ty_name).then(|| ())
-}
-
 /// Checks if the type is an Iterator from std::iter and replaces its hint with an `impl Iterator<Item = Ty>`.
 fn hint_iterator(
     sema: &Semantics<RootDatabase>,
@@ -538,12 +470,10 @@ mod tests {
         max_length: None,
     };
 
-    #[track_caller]
     fn check(ra_fixture: &str) {
         check_with_config(TEST_CONFIG, ra_fixture);
     }
 
-    #[track_caller]
     fn check_params(ra_fixture: &str) {
         check_with_config(
             InlayHintsConfig {
@@ -556,7 +486,6 @@ mod tests {
         );
     }
 
-    #[track_caller]
     fn check_types(ra_fixture: &str) {
         check_with_config(
             InlayHintsConfig {
@@ -569,7 +498,6 @@ mod tests {
         );
     }
 
-    #[track_caller]
     fn check_chains(ra_fixture: &str) {
         check_with_config(
             InlayHintsConfig {
@@ -582,7 +510,6 @@ mod tests {
         );
     }
 
-    #[track_caller]
     fn check_with_config(config: InlayHintsConfig, ra_fixture: &str) {
         let (analysis, file_id) = fixture::file(&ra_fixture);
         let expected = extract_annotations(&*analysis.file_text(file_id).unwrap());
@@ -592,7 +519,6 @@ mod tests {
         assert_eq!(expected, actual, "\nExpected:\n{:#?}\n\nActual:\n{:#?}", expected, actual);
     }
 
-    #[track_caller]
     fn check_expect(config: InlayHintsConfig, ra_fixture: &str, expect: Expect) {
         let (analysis, file_id) = fixture::file(&ra_fixture);
         let inlay_hints = analysis.inlay_hints(&config, file_id).unwrap();
@@ -1265,12 +1191,11 @@ trait Display {}
 trait Sync {}
 
 fn main() {
-    // The block expression wrapping disables the constructor hint hiding logic
-    let _v = { Vec::<Box<&(dyn Display + Sync)>>::new() };
+    let _v = Vec::<Box<&(dyn Display + Sync)>>::new();
       //^^ Vec<Box<&(dyn Display + Sync)>>
-    let _v = { Vec::<Box<*const (dyn Display + Sync)>>::new() };
+    let _v = Vec::<Box<*const (dyn Display + Sync)>>::new();
       //^^ Vec<Box<*const (dyn Display + Sync)>>
-    let _v = { Vec::<Box<dyn Display + Sync>>::new() };
+    let _v = Vec::<Box<dyn Display + Sync>>::new();
       //^^ Vec<Box<dyn Display + Sync>>
 }
 "#,
@@ -1309,48 +1234,6 @@ fn main() {
         );
     }
 
-    #[test]
-    fn skip_constructor_type_hints() {
-        check_types(
-            r#"
-//- minicore: try
-use core::ops::ControlFlow;
-
-struct Struct;
-struct TupleStruct();
-
-impl Struct {
-    fn new() -> Self {
-        Struct
-    }
-    fn try_new() -> ControlFlow<(), Self> {
-        ControlFlow::Continue(Struct)
-    }
-}
-
-struct Generic<T>(T);
-impl Generic<i32> {
-    fn new() -> Self {
-        Generic(0)
-    }
-}
-
-fn main() {
-    let strukt = Struct::new();
-    let tuple_struct = TupleStruct();
-    let generic0 = Generic::new();
-     // ^^^^^^^^ Generic<i32>
-    let generic1 = Generic::<i32>::new();
-    let generic2 = <Generic<i32>>::new();
-}
-
-fn fallible() -> ControlFlow<()> {
-    let strukt = Struct::try_new()?;
-}
-"#,
-        );
-    }
-
     #[test]
     fn closures() {
         check(
diff --git a/crates/ide/src/join_lines.rs b/crates/ide/src/join_lines.rs
index 000d74abac..4851f9aee0 100644
--- a/crates/ide/src/join_lines.rs
+++ b/crates/ide/src/join_lines.rs
@@ -136,10 +136,9 @@ fn remove_newline(
             }
             T!['}'] => {
                 // Removes: comma, newline (incl. surrounding whitespace)
-                let space = if let Some(left) = prev.prev_sibling_or_token() {
-                    compute_ws(left.kind(), next.kind())
-                } else {
-                    " "
+                let space = match prev.prev_sibling_or_token() {
+                    Some(left) => compute_ws(left.kind(), next.kind()),
+                    None => " ",
                 };
                 edit.replace(
                     TextRange::new(prev.text_range().start(), token.text_range().end()),
diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs
index cce342272f..e02c0dfd84 100644
--- a/crates/ide/src/rename.rs
+++ b/crates/ide/src/rename.rs
@@ -156,7 +156,7 @@ fn rename_to_self(sema: &Semantics<RootDatabase>, local: hir::Local) -> RenameRe
         _ => bail!("Cannot rename local to self outside of function"),
     };
 
-    if let Some(_) = fn_def.self_param(sema.db) {
+    if fn_def.self_param(sema.db).is_some() {
         bail!("Method already has a self parameter");
     }
 
diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs
index aa62e2eae5..eb1a04c3f7 100644
--- a/crates/ide/src/static_index.rs
+++ b/crates/ide/src/static_index.rs
@@ -103,10 +103,9 @@ impl StaticIndex<'_> {
         for token in tokens {
             let range = token.text_range();
             let node = token.parent().unwrap();
-            let def = if let Some(x) = get_definition(&sema, token.clone()) {
-                x
-            } else {
-                continue;
+            let def = match get_definition(&sema, token.clone()) {
+                Some(x) => x,
+                None => continue,
             };
             let id = if let Some(x) = self.def_map.get(&def) {
                 *x
@@ -124,10 +123,9 @@ impl StaticIndex<'_> {
             let token = self.tokens.get_mut(id).unwrap();
             token.references.push(ReferenceData {
                 range: FileRange { range, file_id },
-                is_definition: if let Some(x) = def.try_to_nav(self.db) {
-                    x.file_id == file_id && x.focus_or_full_range() == range
-                } else {
-                    false
+                is_definition: match def.try_to_nav(self.db) {
+                    Some(x) => x.file_id == file_id && x.focus_or_full_range() == range,
+                    None => false,
                 },
             });
             result.tokens.push((range, id));
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs
index 03d513fe4d..c4577e6350 100644
--- a/crates/ide/src/syntax_highlighting.rs
+++ b/crates/ide/src/syntax_highlighting.rs
@@ -330,7 +330,7 @@ fn traverse(
             }
         }
 
-        if let Some(_) = macro_highlighter.highlight(element_to_highlight.clone()) {
+        if macro_highlighter.highlight(element_to_highlight.clone()).is_some() {
             continue;
         }
 
diff --git a/crates/ide_assists/src/handlers/convert_while_to_loop.rs b/crates/ide_assists/src/handlers/convert_while_to_loop.rs
index 2ecf646252..92dc2ee73a 100644
--- a/crates/ide_assists/src/handlers/convert_while_to_loop.rs
+++ b/crates/ide_assists/src/handlers/convert_while_to_loop.rs
@@ -44,7 +44,7 @@ pub(crate) fn convert_while_to_loop(acc: &mut Assists, ctx: &AssistContext) -> O
     let cond = while_expr.condition()?;
 
     // Don't handle while let
-    if let Some(_) = cond.pat() {
+    if cond.pat().is_some() {
         return None;
     };
 
diff --git a/crates/ide_assists/src/handlers/extract_function.rs b/crates/ide_assists/src/handlers/extract_function.rs
index 2e91f8d4ab..b7eb2aefad 100644
--- a/crates/ide_assists/src/handlers/extract_function.rs
+++ b/crates/ide_assists/src/handlers/extract_function.rs
@@ -827,10 +827,9 @@ impl FunctionBody {
         locals
             .map(|local| (local, local.source(ctx.db())))
             .filter(|(_, src)| is_defined_outside_of_body(ctx, self, src))
-            .filter_map(|(local, src)| {
-                if let Either::Left(src) = src.value {
-                    Some((local, src))
-                } else {
+            .filter_map(|(local, src)| match src.value {
+                Either::Left(src) => Some((local, src)),
+                Either::Right(_) => {
                     stdx::never!(false, "Local::is_self returned false, but source is SelfParam");
                     None
                 }
@@ -1090,7 +1089,7 @@ fn make_call(ctx: &AssistContext, fun: &Function, indent: IndentLevel) -> String
 
     let args = make::arg_list(fun.params.iter().map(|param| param.to_arg(ctx)));
     let name = fun.name.clone();
-    let mut call_expr = if fun.self_param.is_some() {
+    let call_expr = if fun.self_param.is_some() {
         let self_arg = make::expr_path(make::ext::ident_path("self"));
         make::expr_method_call(self_arg, name, args)
     } else {
@@ -1100,9 +1099,6 @@ fn make_call(ctx: &AssistContext, fun: &Function, indent: IndentLevel) -> String
 
     let handler = FlowHandler::from_ret_ty(fun, &ret_ty);
 
-    if fun.control_flow.is_async {
-        call_expr = make::expr_await(call_expr);
-    }
     let expr = handler.make_call_expr(call_expr).indent(indent);
 
     let mut_modifier = |var: &OutlivedLocal| if var.mut_usage_outside_body { "mut " } else { "" };
@@ -1122,8 +1118,10 @@ fn make_call(ctx: &AssistContext, fun: &Function, indent: IndentLevel) -> String
             buf.push_str(") = ");
         }
     }
-
     format_to!(buf, "{}", expr);
+    if fun.control_flow.is_async {
+        buf.push_str(".await");
+    }
     let insert_comma = fun
         .body
         .parent()
@@ -3871,70 +3869,6 @@ async fn $0fun_name() {
 
 async fn some_function() {
 
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn extract_with_await_and_result_not_producing_match_expr() {
-        check_assist(
-            extract_function,
-            r#"
-async fn foo() -> Result<(), ()> {
-    $0async {}.await;
-    Err(())?$0
-}
-"#,
-            r#"
-async fn foo() -> Result<(), ()> {
-    fun_name().await?
-}
-
-async fn $0fun_name() -> _ {
-    async {}.await;
-    Err(())?
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn extract_with_await_and_result_producing_match_expr() {
-        check_assist(
-            extract_function,
-            r#"
-async fn foo() -> i32 {
-    loop {
-        let n = 1;$0
-        let k = async { 1 }.await;
-        if k == 42 {
-            break 3;
-        }
-        let m = k + 1;$0
-        let h = 1 + m;
-    }
-}
-"#,
-            r#"
-async fn foo() -> i32 {
-    loop {
-        let n = 1;
-        let m = match fun_name().await {
-            Ok(value) => value,
-            Err(value) => break value,
-        };
-        let h = 1 + m;
-    }
-}
-
-async fn $0fun_name() -> Result<i32, i32> {
-    let k = async { 1 }.await;
-    if k == 42 {
-        return Err(3);
-    }
-    let m = k + 1;
-    Ok(m)
 }
 "#,
         );
diff --git a/crates/ide_assists/src/handlers/extract_variable.rs b/crates/ide_assists/src/handlers/extract_variable.rs
index 55e5da7fe7..419bf27877 100644
--- a/crates/ide_assists/src/handlers/extract_variable.rs
+++ b/crates/ide_assists/src/handlers/extract_variable.rs
@@ -1,7 +1,6 @@
 use stdx::format_to;
 use syntax::{
     ast::{self, AstNode},
-    NodeOrToken,
     SyntaxKind::{
         BLOCK_EXPR, BREAK_EXPR, CLOSURE_EXPR, COMMENT, LOOP_EXPR, MATCH_ARM, MATCH_GUARD,
         PATH_EXPR, RETURN_EXPR,
@@ -31,26 +30,20 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option
     if ctx.frange.range.is_empty() {
         return None;
     }
-    let node = match ctx.covering_element() {
-        NodeOrToken::Node(it) => it,
-        NodeOrToken::Token(it) if it.kind() == COMMENT => {
-            cov_mark::hit!(extract_var_in_comment_is_not_applicable);
-            return None;
-        }
-        NodeOrToken::Token(it) => it.parent()?,
-    };
-    let node = node.ancestors().take_while(|anc| anc.text_range() == node.text_range()).last()?;
+    let node = ctx.covering_element();
+    if node.kind() == COMMENT {
+        cov_mark::hit!(extract_var_in_comment_is_not_applicable);
+        return None;
+    }
     let to_extract = node
-        .descendants()
-        .take_while(|it| ctx.frange.range.contains_range(it.text_range()))
+        .ancestors()
+        .take_while(|it| it.text_range().contains_range(ctx.frange.range))
         .find_map(valid_target_expr)?;
-
     if let Some(ty_info) = ctx.sema.type_of_expr(&to_extract) {
         if ty_info.adjusted().is_unit() {
             return None;
         }
     }
-
     let anchor = Anchor::from(&to_extract)?;
     let indent = anchor.syntax().prev_sibling_or_token()?.as_token()?.clone();
     let target = to_extract.syntax().text_range();
@@ -76,10 +69,11 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option
                 None => to_extract.syntax().text_range(),
             };
 
-            if let Anchor::WrapInBlock(_) = anchor {
-                format_to!(buf, "{{ let {} = ", var_name);
-            } else {
-                format_to!(buf, "let {} = ", var_name);
+            match anchor {
+                Anchor::Before(_) | Anchor::Replace(_) => {
+                    format_to!(buf, "let {} = ", var_name)
+                }
+                Anchor::WrapInBlock(_) => format_to!(buf, "{{ let {} = ", var_name),
             };
             format_to!(buf, "{}", to_extract.syntax());
 
@@ -153,11 +147,8 @@ enum Anchor {
 
 impl Anchor {
     fn from(to_extract: &ast::Expr) -> Option<Anchor> {
-        to_extract
-            .syntax()
-            .ancestors()
-            .take_while(|it| !ast::Item::can_cast(it.kind()) || ast::MacroCall::can_cast(it.kind()))
-            .find_map(|node| {
+        to_extract.syntax().ancestors().take_while(|it| !ast::Item::can_cast(it.kind())).find_map(
+            |node| {
                 if let Some(expr) =
                     node.parent().and_then(ast::StmtList::cast).and_then(|it| it.tail_expr())
                 {
@@ -191,7 +182,8 @@ impl Anchor {
                     return Some(Anchor::Before(node));
                 }
                 None
-            })
+            },
+        )
     }
 
     fn syntax(&self) -> &SyntaxNode {
diff --git a/crates/ide_assists/src/handlers/generate_function.rs b/crates/ide_assists/src/handlers/generate_function.rs
index 64e5c23f7c..ea3656ed21 100644
--- a/crates/ide_assists/src/handlers/generate_function.rs
+++ b/crates/ide_assists/src/handlers/generate_function.rs
@@ -51,6 +51,27 @@ pub(crate) fn generate_function(acc: &mut Assists, ctx: &AssistContext) -> Optio
     gen_fn(acc, ctx).or_else(|| gen_method(acc, ctx))
 }
 
+enum FuncExpr {
+    Func(ast::CallExpr),
+    Method(ast::MethodCallExpr),
+}
+
+impl FuncExpr {
+    fn arg_list(&self) -> Option<ast::ArgList> {
+        match self {
+            FuncExpr::Func(fn_call) => fn_call.arg_list(),
+            FuncExpr::Method(m_call) => m_call.arg_list(),
+        }
+    }
+
+    fn syntax(&self) -> &SyntaxNode {
+        match self {
+            FuncExpr::Func(fn_call) => fn_call.syntax(),
+            FuncExpr::Method(m_call) => m_call.syntax(),
+        }
+    }
+}
+
 fn gen_fn(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
     let path_expr: ast::PathExpr = ctx.find_node_at_offset()?;
     let call = path_expr.syntax().parent().and_then(ast::CallExpr::cast)?;
@@ -192,10 +213,9 @@ impl FunctionTemplate {
             Some(cap) => {
                 let cursor = if self.should_focus_return_type {
                     // Focus the return type if there is one
-                    if let Some(ref ret_type) = self.ret_type {
-                        ret_type.syntax()
-                    } else {
-                        self.tail_expr.syntax()
+                    match self.ret_type {
+                        Some(ref ret_type) => ret_type.syntax(),
+                        None => self.tail_expr.syntax(),
                     }
                 } else {
                     self.tail_expr.syntax()
@@ -233,8 +253,7 @@ impl FunctionBuilder {
         let needs_pub = target_module.is_some();
         let target_module = target_module.or_else(|| current_module(target.syntax(), ctx))?;
         let fn_name = make::name(fn_name);
-        let (type_params, params) =
-            fn_args(ctx, target_module, ast::CallableExpr::Call(call.clone()))?;
+        let (type_params, params) = fn_args(ctx, target_module, FuncExpr::Func(call.clone()))?;
 
         let await_expr = call.syntax().parent().and_then(ast::AwaitExpr::cast);
         let is_async = await_expr.is_some();
@@ -264,8 +283,7 @@ impl FunctionBuilder {
         let needs_pub =
             !module_is_descendant(&current_module(call.syntax(), ctx)?, &target_module, ctx);
         let fn_name = make::name(&name.text());
-        let (type_params, params) =
-            fn_args(ctx, target_module, ast::CallableExpr::MethodCall(call.clone()))?;
+        let (type_params, params) = fn_args(ctx, target_module, FuncExpr::Method(call.clone()))?;
 
         let await_expr = call.syntax().parent().and_then(ast::AwaitExpr::cast);
         let is_async = await_expr.is_some();
@@ -373,7 +391,7 @@ fn get_fn_target(
             file = in_file;
             target
         }
-        None => next_space_for_fn_after_call_site(ast::CallableExpr::Call(call))?,
+        None => next_space_for_fn_after_call_site(FuncExpr::Func(call))?,
     };
     Some((target.clone(), file, get_insert_offset(&target)))
 }
@@ -419,7 +437,7 @@ impl GeneratedFunctionTarget {
 fn fn_args(
     ctx: &AssistContext,
     target_module: hir::Module,
-    call: ast::CallableExpr,
+    call: FuncExpr,
 ) -> Option<(Option<ast::GenericParamList>, ast::ParamList)> {
     let mut arg_names = Vec::new();
     let mut arg_types = Vec::new();
@@ -428,10 +446,9 @@ fn fn_args(
         arg_types.push(match fn_arg_type(ctx, target_module, &arg) {
             Some(ty) => {
                 if !ty.is_empty() && ty.starts_with('&') {
-                    if let Some((new_ty, _)) = useless_type_special_case("", &ty[1..].to_owned()) {
-                        new_ty
-                    } else {
-                        ty
+                    match useless_type_special_case("", &ty[1..].to_owned()) {
+                        Some((new_ty, _)) => new_ty,
+                        None => ty,
                     }
                 } else {
                     ty
@@ -449,8 +466,8 @@ fn fn_args(
         None,
         make::param_list(
             match call {
-                ast::CallableExpr::Call(_) => None,
-                ast::CallableExpr::MethodCall(_) => Some(make::self_param()),
+                FuncExpr::Func(_) => None,
+                FuncExpr::Method(_) => Some(make::self_param()),
             },
             params,
         ),
@@ -523,18 +540,14 @@ fn fn_arg_type(
         return None;
     }
 
-    if let Ok(rendered) = ty.display_source_code(ctx.db(), target_module.into()) {
-        Some(rendered)
-    } else {
-        None
-    }
+    ty.display_source_code(ctx.db(), target_module.into()).ok()
 }
 
 /// Returns the position inside the current mod or file
 /// directly after the current block
 /// We want to write the generated function directly after
 /// fns, impls or macro calls, but inside mods
-fn next_space_for_fn_after_call_site(expr: ast::CallableExpr) -> Option<GeneratedFunctionTarget> {
+fn next_space_for_fn_after_call_site(expr: FuncExpr) -> Option<GeneratedFunctionTarget> {
     let mut ancestors = expr.syntax().ancestors().peekable();
     let mut last_ancestor: Option<SyntaxNode> = None;
     while let Some(next_ancestor) = ancestors.next() {
@@ -560,20 +573,14 @@ fn next_space_for_fn_in_module(
 ) -> Option<(FileId, GeneratedFunctionTarget)> {
     let file = module_source.file_id.original_file(db);
     let assist_item = match &module_source.value {
-        hir::ModuleSource::SourceFile(it) => {
-            if let Some(last_item) = it.items().last() {
-                GeneratedFunctionTarget::BehindItem(last_item.syntax().clone())
-            } else {
-                GeneratedFunctionTarget::BehindItem(it.syntax().clone())
-            }
-        }
-        hir::ModuleSource::Module(it) => {
-            if let Some(last_item) = it.item_list().and_then(|it| it.items().last()) {
-                GeneratedFunctionTarget::BehindItem(last_item.syntax().clone())
-            } else {
-                GeneratedFunctionTarget::InEmptyItemList(it.item_list()?.syntax().clone())
-            }
-        }
+        hir::ModuleSource::SourceFile(it) => match it.items().last() {
+            Some(last_item) => GeneratedFunctionTarget::BehindItem(last_item.syntax().clone()),
+            None => GeneratedFunctionTarget::BehindItem(it.syntax().clone()),
+        },
+        hir::ModuleSource::Module(it) => match it.item_list().and_then(|it| it.items().last()) {
+            Some(last_item) => GeneratedFunctionTarget::BehindItem(last_item.syntax().clone()),
+            None => GeneratedFunctionTarget::InEmptyItemList(it.item_list()?.syntax().clone()),
+        },
         hir::ModuleSource::BlockExpr(it) => {
             if let Some(last_item) =
                 it.statements().take_while(|stmt| matches!(stmt, ast::Stmt::Item(_))).last()
diff --git a/crates/ide_assists/src/handlers/inline_call.rs b/crates/ide_assists/src/handlers/inline_call.rs
index b3dc95df41..091f015ee0 100644
--- a/crates/ide_assists/src/handlers/inline_call.rs
+++ b/crates/ide_assists/src/handlers/inline_call.rs
@@ -12,7 +12,7 @@ use ide_db::{
 use itertools::{izip, Itertools};
 use syntax::{
     ast::{self, edit_in_place::Indent, HasArgList, PathExpr},
-    ted, AstNode,
+    ted, AstNode, SyntaxNode,
 };
 
 use crate::{
@@ -141,10 +141,9 @@ pub(crate) fn inline_into_callers(acc: &mut Assists, ctx: &AssistContext) -> Opt
             for (file_id, refs) in usages.into_iter() {
                 inline_refs_for_file(file_id, refs);
             }
-            if let Some(refs) = current_file_usage {
-                inline_refs_for_file(def_file, refs);
-            } else {
-                builder.edit_file(def_file);
+            match current_file_usage {
+                Some(refs) => inline_refs_for_file(def_file, refs),
+                None => builder.edit_file(def_file),
             }
             if remove_def {
                 builder.delete(ast_func.syntax().text_range());
@@ -178,7 +177,7 @@ pub(crate) fn inline_call(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
     let name_ref: ast::NameRef = ctx.find_node_at_offset()?;
     let call_info = CallInfo::from_name_ref(name_ref.clone())?;
     let (function, label) = match &call_info.node {
-        ast::CallableExpr::Call(call) => {
+        CallExprNode::Call(call) => {
             let path = match call.expr()? {
                 ast::Expr::PathExpr(path) => path.path(),
                 _ => None,
@@ -190,7 +189,7 @@ pub(crate) fn inline_call(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
             };
             (function, format!("Inline `{}`", path))
         }
-        ast::CallableExpr::MethodCall(call) => {
+        CallExprNode::MethodCallExpr(call) => {
             (ctx.sema.resolve_method_call(call)?, format!("Inline `{}`", name_ref))
         }
     };
@@ -223,8 +222,8 @@ pub(crate) fn inline_call(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
 
             builder.replace_ast(
                 match call_info.node {
-                    ast::CallableExpr::Call(it) => ast::Expr::CallExpr(it),
-                    ast::CallableExpr::MethodCall(it) => ast::Expr::MethodCallExpr(it),
+                    CallExprNode::Call(it) => ast::Expr::CallExpr(it),
+                    CallExprNode::MethodCallExpr(it) => ast::Expr::MethodCallExpr(it),
                 },
                 replacement,
             );
@@ -232,8 +231,22 @@ pub(crate) fn inline_call(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
     )
 }
 
+enum CallExprNode {
+    Call(ast::CallExpr),
+    MethodCallExpr(ast::MethodCallExpr),
+}
+
+impl CallExprNode {
+    fn syntax(&self) -> &SyntaxNode {
+        match self {
+            CallExprNode::Call(it) => it.syntax(),
+            CallExprNode::MethodCallExpr(it) => it.syntax(),
+        }
+    }
+}
+
 struct CallInfo {
-    node: ast::CallableExpr,
+    node: CallExprNode,
     arguments: Vec<ast::Expr>,
     generic_arg_list: Option<ast::GenericArgList>,
 }
@@ -247,7 +260,7 @@ impl CallInfo {
             arguments.extend(call.arg_list()?.args());
             Some(CallInfo {
                 generic_arg_list: call.generic_arg_list(),
-                node: ast::CallableExpr::MethodCall(call),
+                node: CallExprNode::MethodCallExpr(call),
                 arguments,
             })
         } else if let Some(segment) = ast::PathSegment::cast(parent) {
@@ -257,7 +270,7 @@ impl CallInfo {
 
             Some(CallInfo {
                 arguments: call.arg_list()?.args().collect(),
-                node: ast::CallableExpr::Call(call),
+                node: CallExprNode::Call(call),
                 generic_arg_list: segment.generic_arg_list(),
             })
         } else {
@@ -353,9 +366,8 @@ fn inline(
                 ted::replace(usage.syntax(), &replacement.syntax().clone_for_update());
             }
         };
-        // izip confuses RA due to our lack of hygiene info currently losing us type info causing incorrect errors
+        // izip confuses RA due to our lack of hygiene info currently losing us typeinfo
         let usages: &[ast::PathExpr] = &*usages;
-        let expr: &ast::Expr = expr;
         match usages {
             // inline single use closure arguments
             [usage]
@@ -401,8 +413,8 @@ fn inline(
     }
 
     let original_indentation = match node {
-        ast::CallableExpr::Call(it) => it.indent_level(),
-        ast::CallableExpr::MethodCall(it) => it.indent_level(),
+        CallExprNode::Call(it) => it.indent_level(),
+        CallExprNode::MethodCallExpr(it) => it.indent_level(),
     };
     body.reindent_to(original_indentation);
 
diff --git a/crates/ide_assists/src/handlers/pull_assignment_up.rs b/crates/ide_assists/src/handlers/pull_assignment_up.rs
index 8946ecfac7..d142397c24 100644
--- a/crates/ide_assists/src/handlers/pull_assignment_up.rs
+++ b/crates/ide_assists/src/handlers/pull_assignment_up.rs
@@ -127,12 +127,9 @@ impl<'a> AssignmentsCollector<'a> {
         }
     }
     fn collect_block(&mut self, block: &ast::BlockExpr) -> Option<()> {
-        let last_expr = block.tail_expr().or_else(|| {
-            if let ast::Stmt::ExprStmt(stmt) = block.statements().last()? {
-                stmt.expr()
-            } else {
-                None
-            }
+        let last_expr = block.tail_expr().or_else(|| match block.statements().last()? {
+            ast::Stmt::ExprStmt(stmt) => stmt.expr(),
+            ast::Stmt::Item(_) | ast::Stmt::LetStmt(_) => None,
         })?;
 
         if let ast::Expr::BinExpr(expr) = last_expr {
diff --git a/crates/ide_assists/src/handlers/qualify_path.rs b/crates/ide_assists/src/handlers/qualify_path.rs
index 8a2ec8ba80..0b33acc39b 100644
--- a/crates/ide_assists/src/handlers/qualify_path.rs
+++ b/crates/ide_assists/src/handlers/qualify_path.rs
@@ -181,10 +181,9 @@ fn find_trait_method(
 fn item_as_trait(db: &RootDatabase, item: hir::ItemInNs) -> Option<hir::Trait> {
     let item_module_def = item.as_module_def()?;
 
-    if let hir::ModuleDef::Trait(trait_) = item_module_def {
-        Some(trait_)
-    } else {
-        item_module_def.as_assoc_item(db)?.containing_trait(db)
+    match item_module_def {
+        hir::ModuleDef::Trait(trait_) => Some(trait_),
+        _ => item_module_def.as_assoc_item(db)?.containing_trait(db),
     }
 }
 
diff --git a/crates/ide_assists/src/utils.rs b/crates/ide_assists/src/utils.rs
index dfb22afc7e..3d4ab968fb 100644
--- a/crates/ide_assists/src/utils.rs
+++ b/crates/ide_assists/src/utils.rs
@@ -250,13 +250,10 @@ fn invert_special_case(expr: &ast::Expr) -> Option<ast::Expr> {
             };
             Some(make::expr_method_call(receiver, make::name_ref(method), arg_list))
         }
-        ast::Expr::PrefixExpr(pe) if pe.op_kind()? == ast::UnaryOp::Not => {
-            if let ast::Expr::ParenExpr(parexpr) = pe.expr()? {
-                parexpr.expr()
-            } else {
-                pe.expr()
-            }
-        }
+        ast::Expr::PrefixExpr(pe) if pe.op_kind()? == ast::UnaryOp::Not => match pe.expr()? {
+            ast::Expr::ParenExpr(parexpr) => parexpr.expr(),
+            _ => pe.expr(),
+        },
         ast::Expr::Literal(lit) => match lit.kind() {
             ast::LiteralKind::Bool(b) => match b {
                 true => Some(ast::Expr::Literal(make::expr_literal("false"))),
@@ -276,13 +273,10 @@ pub(crate) fn does_pat_match_variant(pat: &ast::Pat, var: &ast::Pat) -> bool {
     let first_node_text = |pat: &ast::Pat| pat.syntax().first_child().map(|node| node.text());
 
     let pat_head = match pat {
-        ast::Pat::IdentPat(bind_pat) => {
-            if let Some(p) = bind_pat.pat() {
-                first_node_text(&p)
-            } else {
-                return pat.syntax().text() == var.syntax().text();
-            }
-        }
+        ast::Pat::IdentPat(bind_pat) => match bind_pat.pat() {
+            Some(p) => first_node_text(&p),
+            None => return pat.syntax().text() == var.syntax().text(),
+        },
         pat => first_node_text(pat),
     };
 
diff --git a/crates/ide_assists/src/utils/suggest_name.rs b/crates/ide_assists/src/utils/suggest_name.rs
index 35e2300196..74523234b0 100644
--- a/crates/ide_assists/src/utils/suggest_name.rs
+++ b/crates/ide_assists/src/utils/suggest_name.rs
@@ -144,10 +144,9 @@ fn is_valid_name(name: &str) -> bool {
 fn is_useless_method(method: &ast::MethodCallExpr) -> bool {
     let ident = method.name_ref().and_then(|it| it.ident_token());
 
-    if let Some(ident) = ident {
-        USELESS_METHODS.contains(&ident.text())
-    } else {
-        false
+    match ident {
+        Some(ident) => USELESS_METHODS.contains(&ident.text()),
+        None => false,
     }
 }
 
diff --git a/crates/ide_completion/src/completions/postfix.rs b/crates/ide_completion/src/completions/postfix.rs
index 55c49c2322..7edd2e2876 100644
--- a/crates/ide_completion/src/completions/postfix.rs
+++ b/crates/ide_completion/src/completions/postfix.rs
@@ -53,14 +53,14 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
         Some(it) => it,
         None => return,
     };
-
-    let postfix_snippet = build_postfix_snippet_builder(ctx, cap, &dot_receiver);
-
     let try_enum = TryEnum::from_ty(&ctx.sema, &receiver_ty.strip_references());
     if let Some(try_enum) = &try_enum {
         match try_enum {
             TryEnum::Result => {
                 postfix_snippet(
+                    ctx,
+                    cap,
+                    dot_receiver,
                     "ifl",
                     "if let Ok {}",
                     &format!("if let Ok($1) = {} {{\n    $0\n}}", receiver_text),
@@ -68,6 +68,9 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
                 .add_to(acc);
 
                 postfix_snippet(
+                    ctx,
+                    cap,
+                    dot_receiver,
                     "while",
                     "while let Ok {}",
                     &format!("while let Ok($1) = {} {{\n    $0\n}}", receiver_text),
@@ -76,6 +79,9 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
             }
             TryEnum::Option => {
                 postfix_snippet(
+                    ctx,
+                    cap,
+                    dot_receiver,
                     "ifl",
                     "if let Some {}",
                     &format!("if let Some($1) = {} {{\n    $0\n}}", receiver_text),
@@ -83,6 +89,9 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
                 .add_to(acc);
 
                 postfix_snippet(
+                    ctx,
+                    cap,
+                    dot_receiver,
                     "while",
                     "while let Some {}",
                     &format!("while let Some($1) = {} {{\n    $0\n}}", receiver_text),
@@ -91,18 +100,32 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
             }
         }
     } else if receiver_ty.is_bool() || receiver_ty.is_unknown() {
-        postfix_snippet("if", "if expr {}", &format!("if {} {{\n    $0\n}}", receiver_text))
-            .add_to(acc);
         postfix_snippet(
+            ctx,
+            cap,
+            dot_receiver,
+            "if",
+            "if expr {}",
+            &format!("if {} {{\n    $0\n}}", receiver_text),
+        )
+        .add_to(acc);
+        postfix_snippet(
+            ctx,
+            cap,
+            dot_receiver,
             "while",
             "while expr {}",
             &format!("while {} {{\n    $0\n}}", receiver_text),
         )
         .add_to(acc);
-        postfix_snippet("not", "!expr", &format!("!{}", receiver_text)).add_to(acc);
+        postfix_snippet(ctx, cap, dot_receiver, "not", "!expr", &format!("!{}", receiver_text))
+            .add_to(acc);
     } else if let Some(trait_) = FamousDefs(&ctx.sema, ctx.krate).core_iter_IntoIterator() {
         if receiver_ty.impls_trait(ctx.db, trait_, &[]) {
             postfix_snippet(
+                ctx,
+                cap,
+                dot_receiver,
                 "for",
                 "for ele in expr {}",
                 &format!("for ele in {} {{\n    $0\n}}", receiver_text),
@@ -111,19 +134,30 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
         }
     }
 
-    postfix_snippet("ref", "&expr", &format!("&{}", receiver_text)).add_to(acc);
-    postfix_snippet("refm", "&mut expr", &format!("&mut {}", receiver_text)).add_to(acc);
+    postfix_snippet(ctx, cap, dot_receiver, "ref", "&expr", &format!("&{}", receiver_text))
+        .add_to(acc);
+    postfix_snippet(
+        ctx,
+        cap,
+        dot_receiver,
+        "refm",
+        "&mut expr",
+        &format!("&mut {}", receiver_text),
+    )
+    .add_to(acc);
 
     // The rest of the postfix completions create an expression that moves an argument,
     // so it's better to consider references now to avoid breaking the compilation
     let dot_receiver = include_references(dot_receiver);
     let receiver_text = get_receiver_text(&dot_receiver, receiver_is_ambiguous_float_literal);
-    let postfix_snippet = build_postfix_snippet_builder(ctx, cap, &dot_receiver);
 
     match try_enum {
         Some(try_enum) => match try_enum {
             TryEnum::Result => {
                 postfix_snippet(
+                    ctx,
+                    cap,
+                    &dot_receiver,
                     "match",
                     "match expr {}",
                     &format!("match {} {{\n    Ok(${{1:_}}) => {{$2}},\n    Err(${{3:_}}) => {{$0}},\n}}", receiver_text),
@@ -132,6 +166,9 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
             }
             TryEnum::Option => {
                 postfix_snippet(
+                    ctx,
+                    cap,
+                    &dot_receiver,
                     "match",
                     "match expr {}",
                     &format!(
@@ -144,6 +181,9 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
         },
         None => {
             postfix_snippet(
+                ctx,
+                cap,
+                &dot_receiver,
                 "match",
                 "match expr {}",
                 &format!("match {} {{\n    ${{1:_}} => {{$0}},\n}}", receiver_text),
@@ -152,19 +192,89 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
         }
     }
 
-    postfix_snippet("box", "Box::new(expr)", &format!("Box::new({})", receiver_text)).add_to(acc);
-    postfix_snippet("ok", "Ok(expr)", &format!("Ok({})", receiver_text)).add_to(acc);
-    postfix_snippet("err", "Err(expr)", &format!("Err({})", receiver_text)).add_to(acc);
-    postfix_snippet("some", "Some(expr)", &format!("Some({})", receiver_text)).add_to(acc);
-    postfix_snippet("dbg", "dbg!(expr)", &format!("dbg!({})", receiver_text)).add_to(acc);
-    postfix_snippet("dbgr", "dbg!(&expr)", &format!("dbg!(&{})", receiver_text)).add_to(acc);
-    postfix_snippet("call", "function(expr)", &format!("${{1}}({})", receiver_text)).add_to(acc);
+    postfix_snippet(
+        ctx,
+        cap,
+        &dot_receiver,
+        "box",
+        "Box::new(expr)",
+        &format!("Box::new({})", receiver_text),
+    )
+    .add_to(acc);
+
+    postfix_snippet(ctx, cap, &dot_receiver, "ok", "Ok(expr)", &format!("Ok({})", receiver_text))
+        .add_to(acc);
+
+    postfix_snippet(
+        ctx,
+        cap,
+        &dot_receiver,
+        "err",
+        "Err(expr)",
+        &format!("Err({})", receiver_text),
+    )
+    .add_to(acc);
+
+    postfix_snippet(
+        ctx,
+        cap,
+        &dot_receiver,
+        "some",
+        "Some(expr)",
+        &format!("Some({})", receiver_text),
+    )
+    .add_to(acc);
+
+    postfix_snippet(
+        ctx,
+        cap,
+        &dot_receiver,
+        "dbg",
+        "dbg!(expr)",
+        &format!("dbg!({})", receiver_text),
+    )
+    .add_to(acc);
+
+    postfix_snippet(
+        ctx,
+        cap,
+        &dot_receiver,
+        "dbgr",
+        "dbg!(&expr)",
+        &format!("dbg!(&{})", receiver_text),
+    )
+    .add_to(acc);
+
+    postfix_snippet(
+        ctx,
+        cap,
+        &dot_receiver,
+        "call",
+        "function(expr)",
+        &format!("${{1}}({})", receiver_text),
+    )
+    .add_to(acc);
 
     if let Some(parent) = dot_receiver.syntax().parent().and_then(|p| p.parent()) {
         if matches!(parent.kind(), STMT_LIST | EXPR_STMT) {
-            postfix_snippet("let", "let", &format!("let $0 = {};", receiver_text)).add_to(acc);
-            postfix_snippet("letm", "let mut", &format!("let mut $0 = {};", receiver_text))
-                .add_to(acc);
+            postfix_snippet(
+                ctx,
+                cap,
+                &dot_receiver,
+                "let",
+                "let",
+                &format!("let $0 = {};", receiver_text),
+            )
+            .add_to(acc);
+            postfix_snippet(
+                ctx,
+                cap,
+                &dot_receiver,
+                "letm",
+                "let mut",
+                &format!("let mut $0 = {};", receiver_text),
+            )
+            .add_to(acc);
         }
     }
 
@@ -195,27 +305,29 @@ fn include_references(initial_element: &ast::Expr) -> ast::Expr {
     resulting_element
 }
 
-fn build_postfix_snippet_builder<'a>(
-    ctx: &'a CompletionContext,
+fn postfix_snippet(
+    ctx: &CompletionContext,
     cap: SnippetCap,
-    receiver: &'a ast::Expr,
-) -> impl Fn(&str, &str, &str) -> Builder + 'a {
-    let receiver_syntax = receiver.syntax();
-    let receiver_range = ctx.sema.original_range(receiver_syntax).range;
-    let delete_range = TextRange::new(receiver_range.start(), ctx.source_range().end());
-
-    move |label, detail, snippet| {
-        let edit = TextEdit::replace(delete_range, snippet.to_string());
-        let mut item = CompletionItem::new(CompletionKind::Postfix, ctx.source_range(), label);
-        item.detail(detail).kind(CompletionItemKind::Snippet).snippet_edit(cap, edit);
-        if ctx.original_token.text() == label {
-            let relevance =
-                CompletionRelevance { exact_postfix_snippet_match: true, ..Default::default() };
-            item.set_relevance(relevance);
-        }
-
-        item
+    receiver: &ast::Expr,
+    label: &str,
+    detail: &str,
+    snippet: &str,
+) -> Builder {
+    let edit = {
+        let receiver_syntax = receiver.syntax();
+        let receiver_range = ctx.sema.original_range(receiver_syntax).range;
+        let delete_range = TextRange::new(receiver_range.start(), ctx.source_range().end());
+        TextEdit::replace(delete_range, snippet.to_string())
+    };
+    let mut item = CompletionItem::new(CompletionKind::Postfix, ctx.source_range(), label);
+    item.detail(detail).kind(CompletionItemKind::Snippet).snippet_edit(cap, edit);
+    if ctx.original_token.text() == label {
+        let relevance =
+            CompletionRelevance { exact_postfix_snippet_match: true, ..Default::default() };
+        item.set_relevance(relevance);
     }
+
+    item
 }
 
 #[cfg(test)]
diff --git a/crates/ide_completion/src/completions/postfix/format_like.rs b/crates/ide_completion/src/completions/postfix/format_like.rs
index 4fd8d038e7..d4061203c7 100644
--- a/crates/ide_completion/src/completions/postfix/format_like.rs
+++ b/crates/ide_completion/src/completions/postfix/format_like.rs
@@ -19,9 +19,7 @@
 use ide_db::helpers::SnippetCap;
 use syntax::ast::{self, AstToken};
 
-use crate::{
-    completions::postfix::build_postfix_snippet_builder, context::CompletionContext, Completions,
-};
+use crate::{completions::postfix::postfix_snippet, context::CompletionContext, Completions};
 
 /// Mapping ("postfix completion item" => "macro to use")
 static KINDS: &[(&str, &str)] = &[
@@ -49,14 +47,13 @@ pub(crate) fn add_format_like_completions(
         None => return,
     };
 
-    let postfix_snippet = build_postfix_snippet_builder(ctx, cap, dot_receiver);
     let mut parser = FormatStrParser::new(input);
 
     if parser.parse().is_ok() {
         for (label, macro_name) in KINDS {
             let snippet = parser.to_suggestion(macro_name);
 
-            postfix_snippet(label, macro_name, &snippet).add_to(acc);
+            postfix_snippet(ctx, cap, dot_receiver, label, macro_name, &snippet).add_to(acc);
         }
     }
 }
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index ddf8722bc8..d6e15e6af7 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -509,10 +509,9 @@ impl<'a> CompletionContext<'a> {
                             .and_then(|pat| self.sema.type_of_pat(&pat))
                             .or_else(|| it.initializer().and_then(|it| self.sema.type_of_expr(&it)))
                             .map(TypeInfo::original);
-                        let name = if let Some(ast::Pat::IdentPat(ident)) = it.pat() {
-                            ident.name().map(NameOrNameRef::Name)
-                        } else {
-                            None
+                        let name = match it.pat() {
+                            Some(ast::Pat::IdentPat(ident)) => ident.name().map(NameOrNameRef::Name),
+                            Some(_) | None => None,
                         };
 
                         (ty, name)
diff --git a/crates/ide_completion/src/render/function.rs b/crates/ide_completion/src/render/function.rs
index 95244a758d..904624f9ab 100644
--- a/crates/ide_completion/src/render/function.rs
+++ b/crates/ide_completion/src/render/function.rs
@@ -74,10 +74,9 @@ impl<'a> FunctionRender<'a> {
 
     fn render(self, import_to_add: Option<ImportEdit>) -> CompletionItem {
         let params = self.params();
-        let call = if let Some(receiver) = &self.receiver {
-            format!("{}.{}", receiver, &self.name)
-        } else {
-            self.name.clone()
+        let call = match &self.receiver {
+            Some(receiver) => format!("{}.{}", receiver, &self.name),
+            None => self.name.clone(),
         };
         let mut item =
             CompletionItem::new(CompletionKind::Reference, self.ctx.source_range(), call.clone());
diff --git a/crates/ide_completion/src/render/pattern.rs b/crates/ide_completion/src/render/pattern.rs
index 306e418e91..521296fd9b 100644
--- a/crates/ide_completion/src/render/pattern.rs
+++ b/crates/ide_completion/src/render/pattern.rs
@@ -63,10 +63,9 @@ fn build_completion(
         .set_documentation(ctx.docs(def))
         .set_deprecated(ctx.is_deprecated(def))
         .detail(&pat);
-    if let Some(snippet_cap) = ctx.snippet_cap() {
-        item.insert_snippet(snippet_cap, pat);
-    } else {
-        item.insert_text(pat);
+    match ctx.snippet_cap() {
+        Some(snippet_cap) => item.insert_snippet(snippet_cap, pat),
+        None => item.insert_text(pat),
     };
     item.build()
 }
diff --git a/crates/ide_completion/src/render/struct_literal.rs b/crates/ide_completion/src/render/struct_literal.rs
index 68871a4671..810b51effd 100644
--- a/crates/ide_completion/src/render/struct_literal.rs
+++ b/crates/ide_completion/src/render/struct_literal.rs
@@ -38,10 +38,9 @@ fn build_completion(
         .set_documentation(ctx.docs(def))
         .set_deprecated(ctx.is_deprecated(def))
         .detail(&literal);
-    if let Some(snippet_cap) = ctx.snippet_cap() {
-        item.insert_snippet(snippet_cap, literal);
-    } else {
-        item.insert_text(literal);
+    match ctx.snippet_cap() {
+        Some(snippet_cap) => item.insert_snippet(snippet_cap, literal),
+        None => item.insert_text(literal),
     };
     item.build()
 }
diff --git a/crates/ide_db/src/call_info.rs b/crates/ide_db/src/call_info.rs
index 922a411aed..e1d85f0411 100644
--- a/crates/ide_db/src/call_info.rs
+++ b/crates/ide_db/src/call_info.rs
@@ -6,7 +6,7 @@ use stdx::format_to;
 use syntax::{
     algo,
     ast::{self, HasArgList, HasName},
-    AstNode, Direction, SyntaxToken, TextRange, TextSize,
+    match_ast, AstNode, Direction, SyntaxNode, SyntaxToken, TextRange, TextSize,
 };
 
 use crate::RootDatabase;
@@ -25,11 +25,9 @@ impl CallInfo {
     pub fn parameter_labels(&self) -> impl Iterator<Item = &str> + '_ {
         self.parameters.iter().map(move |&it| &self.signature[it])
     }
-
     pub fn parameter_ranges(&self) -> &[TextRange] {
         &self.parameters
     }
-
     fn push_param(&mut self, param: &str) {
         if !self.signature.ends_with('(') {
             self.signature.push_str(", ");
@@ -117,24 +115,31 @@ fn call_info_impl(
     token: SyntaxToken,
 ) -> Option<(hir::Callable, Option<usize>)> {
     // Find the calling expression and it's NameRef
-    let parent = token.parent()?;
-    let calling_node = parent.ancestors().filter_map(ast::CallableExpr::cast).find(|it| {
-        it.arg_list()
-            .map_or(false, |it| it.syntax().text_range().contains(token.text_range().start()))
-    })?;
+    let calling_node = FnCallNode::with_node(&token.parent()?)?;
 
     let callable = match &calling_node {
-        ast::CallableExpr::Call(call) => {
-            let expr = call.expr()?;
-            sema.type_of_expr(&expr)?.adjusted().as_callable(sema.db)
+        FnCallNode::CallExpr(call) => {
+            sema.type_of_expr(&call.expr()?)?.adjusted().as_callable(sema.db)?
         }
-        ast::CallableExpr::MethodCall(call) => sema.resolve_method_call_as_callable(call),
-    }?;
+        FnCallNode::MethodCallExpr(call) => sema.resolve_method_call_as_callable(call)?,
+    };
     let active_param = if let Some(arg_list) = calling_node.arg_list() {
-        let param = arg_list
-            .args()
-            .take_while(|arg| arg.syntax().text_range().end() <= token.text_range().start())
-            .count();
+        // Number of arguments specified at the call site
+        let num_args_at_callsite = arg_list.args().count();
+
+        let arg_list_range = arg_list.syntax().text_range();
+        if !arg_list_range.contains_inclusive(token.text_range().start()) {
+            cov_mark::hit!(call_info_bad_offset);
+            return None;
+        }
+        let param = std::cmp::min(
+            num_args_at_callsite,
+            arg_list
+                .args()
+                .take_while(|arg| arg.syntax().text_range().end() <= token.text_range().start())
+                .count(),
+        );
+
         Some(param)
     } else {
         None
@@ -170,5 +175,60 @@ impl ActiveParameter {
     }
 }
 
+#[derive(Debug)]
+pub enum FnCallNode {
+    CallExpr(ast::CallExpr),
+    MethodCallExpr(ast::MethodCallExpr),
+}
+
+impl FnCallNode {
+    fn with_node(syntax: &SyntaxNode) -> Option<FnCallNode> {
+        syntax.ancestors().find_map(|node| {
+            match_ast! {
+                match node {
+                    ast::CallExpr(it) => Some(FnCallNode::CallExpr(it)),
+                    ast::MethodCallExpr(it) => {
+                        let arg_list = it.arg_list()?;
+                        if !arg_list.syntax().text_range().contains_range(syntax.text_range()) {
+                            return None;
+                        }
+                        Some(FnCallNode::MethodCallExpr(it))
+                    },
+                    _ => None,
+                }
+            }
+        })
+    }
+
+    pub fn with_node_exact(node: &SyntaxNode) -> Option<FnCallNode> {
+        match_ast! {
+            match node {
+                ast::CallExpr(it) => Some(FnCallNode::CallExpr(it)),
+                ast::MethodCallExpr(it) => Some(FnCallNode::MethodCallExpr(it)),
+                _ => None,
+            }
+        }
+    }
+
+    pub fn name_ref(&self) -> Option<ast::NameRef> {
+        match self {
+            FnCallNode::CallExpr(call_expr) => Some(match call_expr.expr()? {
+                ast::Expr::PathExpr(path_expr) => path_expr.path()?.segment()?.name_ref()?,
+                _ => return None,
+            }),
+            FnCallNode::MethodCallExpr(call_expr) => {
+                call_expr.syntax().children().find_map(ast::NameRef::cast)
+            }
+        }
+    }
+
+    fn arg_list(&self) -> Option<ast::ArgList> {
+        match self {
+            FnCallNode::CallExpr(expr) => expr.arg_list(),
+            FnCallNode::MethodCallExpr(expr) => expr.arg_list(),
+        }
+    }
+}
+
 #[cfg(test)]
 mod tests;
diff --git a/crates/ide_db/src/helpers/insert_use.rs b/crates/ide_db/src/helpers/insert_use.rs
index 9889dd772e..a5d1932775 100644
--- a/crates/ide_db/src/helpers/insert_use.rs
+++ b/crates/ide_db/src/helpers/insert_use.rs
@@ -1,4 +1,4 @@
-//! Handle syntactic aspects of inserting a new `use` item.
+//! Handle syntactic aspects of inserting a new `use`.
 #[cfg(test)]
 mod tests;
 
@@ -103,6 +103,81 @@ impl ImportScope {
             ImportScope::Block(block) => ImportScope::Block(block.clone_for_update()),
         }
     }
+
+    fn guess_granularity_from_scope(&self) -> ImportGranularityGuess {
+        // The idea is simple, just check each import as well as the import and its precedent together for
+        // whether they fulfill a granularity criteria.
+        let use_stmt = |item| match item {
+            ast::Item::Use(use_) => {
+                let use_tree = use_.use_tree()?;
+                Some((use_tree, use_.visibility(), use_.attrs()))
+            }
+            _ => None,
+        };
+        let mut use_stmts = match self {
+            ImportScope::File(f) => f.items(),
+            ImportScope::Module(m) => m.items(),
+            ImportScope::Block(b) => b.items(),
+        }
+        .filter_map(use_stmt);
+        let mut res = ImportGranularityGuess::Unknown;
+        let (mut prev, mut prev_vis, mut prev_attrs) = match use_stmts.next() {
+            Some(it) => it,
+            None => return res,
+        };
+        loop {
+            if let Some(use_tree_list) = prev.use_tree_list() {
+                if use_tree_list.use_trees().any(|tree| tree.use_tree_list().is_some()) {
+                    // Nested tree lists can only occur in crate style, or with no proper style being enforced in the file.
+                    break ImportGranularityGuess::Crate;
+                } else {
+                    // Could still be crate-style so continue looking.
+                    res = ImportGranularityGuess::CrateOrModule;
+                }
+            }
+
+            let (curr, curr_vis, curr_attrs) = match use_stmts.next() {
+                Some(it) => it,
+                None => break res,
+            };
+            if eq_visibility(prev_vis, curr_vis.clone()) && eq_attrs(prev_attrs, curr_attrs.clone())
+            {
+                if let Some((prev_path, curr_path)) = prev.path().zip(curr.path()) {
+                    if let Some((prev_prefix, _)) = common_prefix(&prev_path, &curr_path) {
+                        if prev.use_tree_list().is_none() && curr.use_tree_list().is_none() {
+                            let prefix_c = prev_prefix.qualifiers().count();
+                            let curr_c = curr_path.qualifiers().count() - prefix_c;
+                            let prev_c = prev_path.qualifiers().count() - prefix_c;
+                            if curr_c == 1 && prev_c == 1 {
+                                // Same prefix, only differing in the last segment and no use tree lists so this has to be of item style.
+                                break ImportGranularityGuess::Item;
+                            } else {
+                                // Same prefix and no use tree list but differs in more than one segment at the end. This might be module style still.
+                                res = ImportGranularityGuess::ModuleOrItem;
+                            }
+                        } else {
+                            // Same prefix with item tree lists, has to be module style as it
+                            // can't be crate style since the trees wouldn't share a prefix then.
+                            break ImportGranularityGuess::Module;
+                        }
+                    }
+                }
+            }
+            prev = curr;
+            prev_vis = curr_vis;
+            prev_attrs = curr_attrs;
+        }
+    }
+}
+
+#[derive(PartialEq, PartialOrd, Debug, Clone, Copy)]
+enum ImportGranularityGuess {
+    Unknown,
+    Item,
+    Module,
+    ModuleOrItem,
+    Crate,
+    CrateOrModule,
 }
 
 /// Insert an import path into the given file/node. A `merge` value of none indicates that no import merging is allowed to occur.
@@ -114,7 +189,7 @@ pub fn insert_use(scope: &ImportScope, path: ast::Path, cfg: &InsertUseConfig) {
         ImportGranularity::Item | ImportGranularity::Preserve => None,
     };
     if !cfg.enforce_granularity {
-        let file_granularity = guess_granularity_from_scope(scope);
+        let file_granularity = scope.guess_granularity_from_scope();
         mb = match file_granularity {
             ImportGranularityGuess::Unknown => mb,
             ImportGranularityGuess::Item => None,
@@ -196,80 +271,6 @@ impl ImportGroup {
     }
 }
 
-#[derive(PartialEq, PartialOrd, Debug, Clone, Copy)]
-enum ImportGranularityGuess {
-    Unknown,
-    Item,
-    Module,
-    ModuleOrItem,
-    Crate,
-    CrateOrModule,
-}
-
-fn guess_granularity_from_scope(scope: &ImportScope) -> ImportGranularityGuess {
-    // The idea is simple, just check each import as well as the import and its precedent together for
-    // whether they fulfill a granularity criteria.
-    let use_stmt = |item| match item {
-        ast::Item::Use(use_) => {
-            let use_tree = use_.use_tree()?;
-            Some((use_tree, use_.visibility(), use_.attrs()))
-        }
-        _ => None,
-    };
-    let mut use_stmts = match scope {
-        ImportScope::File(f) => f.items(),
-        ImportScope::Module(m) => m.items(),
-        ImportScope::Block(b) => b.items(),
-    }
-    .filter_map(use_stmt);
-    let mut res = ImportGranularityGuess::Unknown;
-    let (mut prev, mut prev_vis, mut prev_attrs) = match use_stmts.next() {
-        Some(it) => it,
-        None => return res,
-    };
-    loop {
-        if let Some(use_tree_list) = prev.use_tree_list() {
-            if use_tree_list.use_trees().any(|tree| tree.use_tree_list().is_some()) {
-                // Nested tree lists can only occur in crate style, or with no proper style being enforced in the file.
-                break ImportGranularityGuess::Crate;
-            } else {
-                // Could still be crate-style so continue looking.
-                res = ImportGranularityGuess::CrateOrModule;
-            }
-        }
-
-        let (curr, curr_vis, curr_attrs) = match use_stmts.next() {
-            Some(it) => it,
-            None => break res,
-        };
-        if eq_visibility(prev_vis, curr_vis.clone()) && eq_attrs(prev_attrs, curr_attrs.clone()) {
-            if let Some((prev_path, curr_path)) = prev.path().zip(curr.path()) {
-                if let Some((prev_prefix, _)) = common_prefix(&prev_path, &curr_path) {
-                    if prev.use_tree_list().is_none() && curr.use_tree_list().is_none() {
-                        let prefix_c = prev_prefix.qualifiers().count();
-                        let curr_c = curr_path.qualifiers().count() - prefix_c;
-                        let prev_c = prev_path.qualifiers().count() - prefix_c;
-                        if curr_c == 1 && prev_c == 1 {
-                            // Same prefix, only differing in the last segment and no use tree lists so this has to be of item style.
-                            break ImportGranularityGuess::Item;
-                        } else {
-                            // Same prefix and no use tree list but differs in more than one segment at the end. This might be module style still.
-                            res = ImportGranularityGuess::ModuleOrItem;
-                        }
-                    } else {
-                        // Same prefix with item tree lists, has to be module style as it
-                        // can't be crate style since the trees wouldn't share a prefix then.
-                        break ImportGranularityGuess::Module;
-                    }
-                }
-            }
-        }
-        prev = curr;
-        prev_vis = curr_vis;
-        prev_attrs = curr_attrs;
-    }
-}
-
 fn insert_use_(
     scope: &ImportScope,
     insert_path: &ast::Path,
diff --git a/crates/ide_db/src/helpers/merge_imports.rs b/crates/ide_db/src/helpers/merge_imports.rs
index 6a7a9b8f61..8189d6e53f 100644
--- a/crates/ide_db/src/helpers/merge_imports.rs
+++ b/crates/ide_db/src/helpers/merge_imports.rs
@@ -19,6 +19,7 @@ pub enum MergeBehavior {
 }
 
 impl MergeBehavior {
+    #[inline]
     fn is_tree_allowed(&self, tree: &ast::UseTree) -> bool {
         match self {
             MergeBehavior::Crate => true,
@@ -113,7 +114,7 @@ fn recursive_merge(
                 let rhs_path = rhs_path?;
                 let (lhs_prefix, rhs_prefix) = common_prefix(&lhs_path, &rhs_path)?;
                 if lhs_prefix == lhs_path && rhs_prefix == rhs_path {
-                    let tree_is_self = |tree: &ast::UseTree| {
+                    let tree_is_self = |tree: ast::UseTree| {
                         tree.path().as_ref().map(path_is_self).unwrap_or(false)
                     };
                     // Check if only one of the two trees has a tree list, and
@@ -122,7 +123,7 @@ fn recursive_merge(
                     // the list is already included in the other one via `self`.
                     let tree_contains_self = |tree: &ast::UseTree| {
                         tree.use_tree_list()
-                            .map(|tree_list| tree_list.use_trees().any(|it| tree_is_self(&it)))
+                            .map(|tree_list| tree_list.use_trees().any(tree_is_self))
                             .unwrap_or(false)
                     };
                     match (tree_contains_self(lhs_t), tree_contains_self(&rhs_t)) {
@@ -140,18 +141,17 @@ fn recursive_merge(
                     // glob import of said module see the `merge_self_glob` or
                     // `merge_mod_into_glob` tests.
                     if lhs_t.star_token().is_some() || rhs_t.star_token().is_some() {
-                        if tree_is_self(lhs_t) || tree_is_self(&rhs_t) {
-                            cov_mark::hit!(merge_self_glob);
-                            *lhs_t = make::use_tree(
-                                make::path_unqualified(make::path_segment_self()),
-                                None,
-                                None,
-                                false,
-                            );
-                            use_trees.insert(idx, make::use_tree_glob());
-                            continue;
-                        }
-                    } else if lhs_t.use_tree_list().is_none() && rhs_t.use_tree_list().is_none() {
+                        *lhs_t = make::use_tree(
+                            make::path_unqualified(make::path_segment_self()),
+                            None,
+                            None,
+                            false,
+                        );
+                        use_trees.insert(idx, make::use_tree_glob());
+                        continue;
+                    }
+
+                    if lhs_t.use_tree_list().is_none() && rhs_t.use_tree_list().is_none() {
                         continue;
                     }
                 }
diff --git a/crates/ide_db/src/rename.rs b/crates/ide_db/src/rename.rs
index fcf1a654b0..4fb5c770e5 100644
--- a/crates/ide_db/src/rename.rs
+++ b/crates/ide_db/src/rename.rs
@@ -318,7 +318,7 @@ pub fn source_edit_from_references(
 }
 
 fn source_edit_from_name(edit: &mut TextEditBuilder, name: &ast::Name, new_name: &str) -> bool {
-    if let Some(_) = ast::RecordPatField::for_field_name(name) {
+    if ast::RecordPatField::for_field_name(name).is_some() {
         if let Some(ident_pat) = name.syntax().parent().and_then(ast::IdentPat::cast) {
             cov_mark::hit!(rename_record_pat_field_name_split);
             // Foo { ref mut field } -> Foo { new_name: ref mut field }
diff --git a/crates/ide_diagnostics/src/handlers/unlinked_file.rs b/crates/ide_diagnostics/src/handlers/unlinked_file.rs
index 5ea58b74fe..cc10a63f87 100644
--- a/crates/ide_diagnostics/src/handlers/unlinked_file.rs
+++ b/crates/ide_diagnostics/src/handlers/unlinked_file.rs
@@ -45,14 +45,16 @@ fn fixes(ctx: &DiagnosticsContext, file_id: FileId) -> Option<Vec<Assist>> {
     // - `$dir.rs` in the parent folder, where `$dir` is the directory containing `self.file_id`
     let parent = our_path.parent()?;
     let paths = {
+        let temp;
         let parent = if module_name == "mod" {
             // for mod.rs we need to actually look up one higher
             // and take the parent as our to be module name
             let (name, _) = parent.name_and_extension()?;
             module_name = name;
-            parent.parent()?
+            temp = parent.parent()?;
+            &temp
         } else {
-            parent
+            &parent
         };
         let mut paths =
             vec![parent.join("mod.rs")?, parent.join("lib.rs")?, parent.join("main.rs")?];
diff --git a/crates/ide_ssr/src/resolving.rs b/crates/ide_ssr/src/resolving.rs
index df20ab375d..9cdd270b80 100644
--- a/crates/ide_ssr/src/resolving.rs
+++ b/crates/ide_ssr/src/resolving.rs
@@ -47,10 +47,9 @@ impl ResolvedRule {
     ) -> Result<ResolvedRule, SsrError> {
         let resolver =
             Resolver { resolution_scope, placeholders_by_stand_in: rule.placeholders_by_stand_in };
-        let resolved_template = if let Some(template) = rule.template {
-            Some(resolver.resolve_pattern_tree(template)?)
-        } else {
-            None
+        let resolved_template = match rule.template {
+            Some(template) => Some(resolver.resolve_pattern_tree(template)?),
+            None => None,
         };
         Ok(ResolvedRule {
             pattern: resolver.resolve_pattern_tree(rule.pattern)?,
diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs
index 3d0ad6735e..991955fca6 100644
--- a/crates/parser/src/grammar.rs
+++ b/crates/parser/src/grammar.rs
@@ -67,11 +67,11 @@ pub(crate) mod entry_points {
     }
 
     pub(crate) fn stmt(p: &mut Parser) {
-        expressions::stmt(p, expressions::StmtWithSemi::No, true)
+        expressions::stmt(p, expressions::StmtWithSemi::No, true);
     }
 
     pub(crate) fn stmt_optional_semi(p: &mut Parser) {
-        expressions::stmt(p, expressions::StmtWithSemi::Optional, false)
+        expressions::stmt(p, expressions::StmtWithSemi::Optional, false);
     }
 
     pub(crate) fn visibility(p: &mut Parser) {
@@ -84,7 +84,7 @@ pub(crate) mod entry_points {
     }
 
     pub(crate) fn item(p: &mut Parser) {
-        items::item_or_macro(p, true)
+        items::item_or_macro(p, true);
     }
 
     pub(crate) fn macro_items(p: &mut Parser) {
@@ -109,7 +109,7 @@ pub(crate) mod entry_points {
     }
 
     pub(crate) fn attr(p: &mut Parser) {
-        attributes::outer_attrs(p)
+        attributes::outer_attrs(p);
     }
 }
 
@@ -128,8 +128,7 @@ pub(crate) fn reparser(
         EXTERN_ITEM_LIST => items::extern_item_list,
         TOKEN_TREE if first_child? == T!['{'] => items::token_tree,
         ASSOC_ITEM_LIST => match parent? {
-            IMPL => items::assoc_item_list,
-            TRAIT => items::assoc_item_list,
+            IMPL | TRAIT => items::assoc_item_list,
             _ => return None,
         },
         ITEM_LIST => items::item_list,
@@ -246,7 +245,7 @@ fn name_r(p: &mut Parser, recovery: TokenSet) {
 }
 
 fn name(p: &mut Parser) {
-    name_r(p, TokenSet::EMPTY)
+    name_r(p, TokenSet::EMPTY);
 }
 
 fn name_ref(p: &mut Parser) {
diff --git a/crates/parser/src/grammar/attributes.rs b/crates/parser/src/grammar/attributes.rs
index 574629f31a..1efffca515 100644
--- a/crates/parser/src/grammar/attributes.rs
+++ b/crates/parser/src/grammar/attributes.rs
@@ -2,13 +2,13 @@ use super::*;
 
 pub(super) fn inner_attrs(p: &mut Parser) {
     while p.at(T![#]) && p.nth(1) == T![!] {
-        attr(p, true)
+        attr(p, true);
     }
 }
 
 pub(super) fn outer_attrs(p: &mut Parser) {
     while p.at(T![#]) {
-        attr(p, false)
+        attr(p, false);
     }
 }
 
diff --git a/crates/parser/src/grammar/expressions.rs b/crates/parser/src/grammar/expressions.rs
index 645101e2f7..aa171674ed 100644
--- a/crates/parser/src/grammar/expressions.rs
+++ b/crates/parser/src/grammar/expressions.rs
@@ -139,7 +139,7 @@ pub(super) fn expr_block_contents(p: &mut Parser) {
             continue;
         }
 
-        stmt(p, StmtWithSemi::Yes, false)
+        stmt(p, StmtWithSemi::Yes, false);
     }
 }
 
@@ -311,7 +311,7 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)>
         _ => {
             // test full_range_expr
             // fn foo() { xs[..]; }
-            for &op in [T![..=], T![..]].iter() {
+            for op in [T![..=], T![..]] {
                 if p.at(op) {
                     m = p.start();
                     p.bump(op);
@@ -468,12 +468,12 @@ fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
     let m = lhs.precede(p);
     p.bump(T![.]);
     if p.at(IDENT) || p.at(INT_NUMBER) {
-        name_ref_or_index(p)
+        name_ref_or_index(p);
     } else if p.at(FLOAT_NUMBER) {
         // FIXME: How to recover and instead parse INT + T![.]?
         p.bump_any();
     } else {
-        p.error("expected field name or number")
+        p.error("expected field name or number");
     }
     m.complete(p, FIELD_EXPR)
 }
diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs
index bfa02aa222..7075ae297f 100644
--- a/crates/parser/src/grammar/expressions/atom.rs
+++ b/crates/parser/src/grammar/expressions/atom.rs
@@ -374,7 +374,7 @@ fn match_expr(p: &mut Parser) -> CompletedMarker {
     if p.at(T!['{']) {
         match_arm_list(p);
     } else {
-        p.error("expected `{`")
+        p.error("expected `{`");
     }
     m.complete(p, MATCH_EXPR)
 }
@@ -602,7 +602,7 @@ fn try_block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
     if p.at(T!['{']) {
         stmt_list(p);
     } else {
-        p.error("expected a block")
+        p.error("expected a block");
     }
     m.complete(p, BLOCK_EXPR)
 }
@@ -639,7 +639,7 @@ fn meta_var_expr(p: &mut Parser) -> CompletedMarker {
         }
         _ => {
             while !p.at(R_DOLLAR) {
-                p.bump_any()
+                p.bump_any();
             }
             p.bump(R_DOLLAR);
             m.complete(p, ERROR)
diff --git a/crates/parser/src/grammar/generic_params.rs b/crates/parser/src/grammar/generic_params.rs
index 5414b3b20d..00ccbf5010 100644
--- a/crates/parser/src/grammar/generic_params.rs
+++ b/crates/parser/src/grammar/generic_params.rs
@@ -34,7 +34,7 @@ fn generic_param(p: &mut Parser) {
         T![const] => const_param(p, m),
         _ => {
             m.abandon(p);
-            p.err_and_bump("expected type parameter")
+            p.err_and_bump("expected type parameter");
         }
     }
 }
@@ -62,7 +62,7 @@ fn type_param(p: &mut Parser, m: Marker) {
         // test type_param_default
         // struct S<T = i32>;
         p.bump(T![=]);
-        types::type_(p)
+        types::type_(p);
     }
     m.complete(p, TYPE_PARAM);
 }
diff --git a/crates/parser/src/grammar/items.rs b/crates/parser/src/grammar/items.rs
index 517da6e95c..9de9afde5d 100644
--- a/crates/parser/src/grammar/items.rs
+++ b/crates/parser/src/grammar/items.rs
@@ -20,7 +20,7 @@ use super::*;
 pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) {
     attributes::inner_attrs(p);
     while !p.at(EOF) && !(p.at(T!['}']) && stop_on_r_curly) {
-        item_or_macro(p, stop_on_r_curly)
+        item_or_macro(p, stop_on_r_curly);
     }
 }
 
@@ -165,7 +165,7 @@ pub(super) fn opt_item(p: &mut Parser, m: Marker) -> Result<(), Marker> {
                     p.bump_remap(T![default]);
                     p.bump(T![async]);
                     if is_unsafe {
-                        p.bump(T![unsafe])
+                        p.bump(T![unsafe]);
                     }
                     has_mods = true;
                 }
@@ -404,7 +404,7 @@ fn fn_(p: &mut Parser, m: Marker) {
         // trait T { fn foo(); }
         p.bump(T![;]);
     } else {
-        expressions::block_expr(p)
+        expressions::block_expr(p);
     }
     m.complete(p, FN);
 }
diff --git a/crates/parser/src/grammar/items/adt.rs b/crates/parser/src/grammar/items/adt.rs
index e4b1116958..42ebecc6d6 100644
--- a/crates/parser/src/grammar/items/adt.rs
+++ b/crates/parser/src/grammar/items/adt.rs
@@ -58,7 +58,7 @@ pub(super) fn enum_(p: &mut Parser, m: Marker) {
     if p.at(T!['{']) {
         variant_list(p);
     } else {
-        p.error("expected `{`")
+        p.error("expected `{`");
     }
     m.complete(p, ENUM);
 }
diff --git a/crates/parser/src/grammar/items/consts.rs b/crates/parser/src/grammar/items/consts.rs
index 93ba7d05fe..98064cd98a 100644
--- a/crates/parser/src/grammar/items/consts.rs
+++ b/crates/parser/src/grammar/items/consts.rs
@@ -4,12 +4,12 @@ use super::*;
 // const C: u32 = 92;
 pub(super) fn konst(p: &mut Parser, m: Marker) {
     p.bump(T![const]);
-    const_or_static(p, m, true)
+    const_or_static(p, m, true);
 }
 
 pub(super) fn static_(p: &mut Parser, m: Marker) {
     p.bump(T![static]);
-    const_or_static(p, m, false)
+    const_or_static(p, m, false);
 }
 
 fn const_or_static(p: &mut Parser, m: Marker, is_const: bool) {
@@ -27,7 +27,7 @@ fn const_or_static(p: &mut Parser, m: Marker, is_const: bool) {
     if p.at(T![:]) {
         types::ascription(p);
     } else {
-        p.error("missing type for `const` or `static`")
+        p.error("missing type for `const` or `static`");
     }
     if p.eat(T![=]) {
         expressions::expr(p);
diff --git a/crates/parser/src/grammar/params.rs b/crates/parser/src/grammar/params.rs
index 8b03ade81f..a000f515cc 100644
--- a/crates/parser/src/grammar/params.rs
+++ b/crates/parser/src/grammar/params.rs
@@ -6,21 +6,21 @@ use super::*;
 // fn c(x: i32, ) {}
 // fn d(x: i32, y: ()) {}
 pub(super) fn param_list_fn_def(p: &mut Parser) {
-    list_(p, Flavor::FnDef)
+    list_(p, Flavor::FnDef);
 }
 
 // test param_list_opt_patterns
 // fn foo<F: FnMut(&mut Foo<'a>)>(){}
 pub(super) fn param_list_fn_trait(p: &mut Parser) {
-    list_(p, Flavor::FnTrait)
+    list_(p, Flavor::FnTrait);
 }
 
 pub(super) fn param_list_fn_ptr(p: &mut Parser) {
-    list_(p, Flavor::FnPointer)
+    list_(p, Flavor::FnPointer);
 }
 
 pub(super) fn param_list_closure(p: &mut Parser) {
-    list_(p, Flavor::Closure)
+    list_(p, Flavor::Closure);
 }
 
 #[derive(Debug, Clone, Copy)]
@@ -104,13 +104,13 @@ fn param(p: &mut Parser, m: Marker, flavor: Flavor) -> Variadic {
         Flavor::FnDef => {
             patterns::pattern(p);
             if variadic_param(p) {
-                res = Variadic(true)
+                res = Variadic(true);
             } else if p.at(T![:]) {
-                types::ascription(p)
+                types::ascription(p);
             } else {
                 // test_err missing_fn_param_type
                 // fn f(x y: i32, z, t: i32) {}
-                p.error("missing type for function parameter")
+                p.error("missing type for function parameter");
             }
         }
         // test value_parameters_no_patterns
@@ -128,11 +128,11 @@ fn param(p: &mut Parser, m: Marker, flavor: Flavor) -> Variadic {
             if (p.at(IDENT) || p.at(UNDERSCORE)) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) {
                 patterns::pattern_single(p);
                 if variadic_param(p) {
-                    res = Variadic(true)
+                    res = Variadic(true);
                 } else if p.at(T![:]) {
-                    types::ascription(p)
+                    types::ascription(p);
                 } else {
-                    p.error("missing type for function parameter")
+                    p.error("missing type for function parameter");
                 }
             } else {
                 types::type_(p);
diff --git a/crates/parser/src/grammar/paths.rs b/crates/parser/src/grammar/paths.rs
index 05a52c984a..0cc0ed31aa 100644
--- a/crates/parser/src/grammar/paths.rs
+++ b/crates/parser/src/grammar/paths.rs
@@ -16,15 +16,15 @@ pub(super) fn is_use_path_start(p: &Parser) -> bool {
 }
 
 pub(super) fn use_path(p: &mut Parser) {
-    path(p, Mode::Use)
+    path(p, Mode::Use);
 }
 
 pub(crate) fn type_path(p: &mut Parser) {
-    path(p, Mode::Type)
+    path(p, Mode::Type);
 }
 
 pub(super) fn expr_path(p: &mut Parser) {
-    path(p, Mode::Expr)
+    path(p, Mode::Expr);
 }
 
 pub(crate) fn type_path_for_qualifier(p: &mut Parser, qual: CompletedMarker) -> CompletedMarker {
@@ -117,7 +117,7 @@ fn opt_path_type_args(p: &mut Parser, mode: Mode) {
                 params::param_list_fn_trait(p);
                 opt_ret_type(p);
             } else {
-                generic_args::opt_generic_arg_list(p, false)
+                generic_args::opt_generic_arg_list(p, false);
             }
         }
         Mode::Expr => generic_args::opt_generic_arg_list(p, true),
diff --git a/crates/parser/src/grammar/patterns.rs b/crates/parser/src/grammar/patterns.rs
index 60a7507c45..7e96823b1d 100644
--- a/crates/parser/src/grammar/patterns.rs
+++ b/crates/parser/src/grammar/patterns.rs
@@ -19,7 +19,7 @@ pub(crate) fn pattern(p: &mut Parser) {
 
 /// Parses a pattern list separated by pipes `|`.
 pub(super) fn pattern_top(p: &mut Parser) {
-    pattern_top_r(p, PAT_RECOVERY_SET)
+    pattern_top_r(p, PAT_RECOVERY_SET);
 }
 
 pub(crate) fn pattern_single(p: &mut Parser) {
@@ -69,23 +69,18 @@ fn pattern_single_r(p: &mut Parser, recovery_set: TokenSet) {
         //         200 .. 301 => (),
         //         302 .. => (),
         //     }
-        //
-        //     match Some(10 as u8) {
-        //         Some(0) | None => (),
-        //         Some(1..) => ()
-        //     }
         // }
 
         // FIXME: support half_open_range_patterns (`..=2`),
         // exclusive_range_pattern (`..5`) with missing lhs
-        for &range_op in [T![...], T![..=], T![..]].iter() {
+        for range_op in [T![...], T![..=], T![..]] {
             if p.at(range_op) {
                 let m = lhs.precede(p);
                 p.bump(range_op);
 
-                // `0 .. =>` or `let 0 .. =` or `Some(0 .. )`
-                //       ^                ^                ^
-                if p.at(T![=]) | p.at(T![')']) {
+                // `0 .. =>` or `let 0 .. =`
+                //       ^                ^
+                if p.at(T![=]) {
                     // test half_open_range_pat
                     // fn f() { let 0 .. = 1u32; }
                 } else {
diff --git a/crates/parser/src/grammar/types.rs b/crates/parser/src/grammar/types.rs
index c2aa9ffc3b..1a6fb651cb 100644
--- a/crates/parser/src/grammar/types.rs
+++ b/crates/parser/src/grammar/types.rs
@@ -57,7 +57,7 @@ fn type_with_bounds_cond(p: &mut Parser, allow_bounds: bool) {
 pub(super) fn ascription(p: &mut Parser) {
     assert!(p.at(T![:]));
     p.bump(T![:]);
-    type_(p)
+    type_(p);
 }
 
 fn paren_or_tuple_type(p: &mut Parser) {
@@ -204,7 +204,7 @@ fn fn_ptr_type(p: &mut Parser) {
     if p.at(T!['(']) {
         params::param_list_fn_ptr(p);
     } else {
-        p.error("expected parameters")
+        p.error("expected parameters");
     }
     // test fn_pointer_type_with_ret
     // type F = fn() -> ();
@@ -274,7 +274,7 @@ fn dyn_trait_type(p: &mut Parser) {
 // type C = self::Foo;
 // type D = super::Foo;
 pub(super) fn path_type(p: &mut Parser) {
-    path_type_(p, true)
+    path_type_(p, true);
 }
 
 // test macro_call_type
diff --git a/crates/parser/src/parser.rs b/crates/parser/src/parser.rs
index 1f9961bb92..89dfea52f8 100644
--- a/crates/parser/src/parser.rs
+++ b/crates/parser/src/parser.rs
@@ -177,7 +177,7 @@ impl<'t> Parser<'t> {
         if kind == EOF {
             return;
         }
-        self.do_bump(kind, 1)
+        self.do_bump(kind, 1);
     }
 
     /// Advances the parser by one token, remapping its kind.
@@ -200,7 +200,7 @@ impl<'t> Parser<'t> {
     /// does.
     pub(crate) fn error<T: Into<String>>(&mut self, message: T) {
         let msg = ParseError(Box::new(message.into()));
-        self.push_event(Event::Error { msg })
+        self.push_event(Event::Error { msg });
     }
 
     /// Consume the next token if it is `kind` or emit an error
@@ -258,7 +258,7 @@ impl<'t> Parser<'t> {
     }
 
     fn push_event(&mut self, event: Event) {
-        self.events.push(event)
+        self.events.push(event);
     }
 }
 
diff --git a/crates/parser/src/token_set.rs b/crates/parser/src/token_set.rs
index a68f0144e7..cd4894c1e8 100644
--- a/crates/parser/src/token_set.rs
+++ b/crates/parser/src/token_set.rs
@@ -14,7 +14,7 @@ impl TokenSet {
         let mut i = 0;
         while i < kinds.len() {
             res |= mask(kinds[i]);
-            i += 1
+            i += 1;
         }
         TokenSet(res)
     }
diff --git a/crates/paths/src/lib.rs b/crates/paths/src/lib.rs
index 90909f4e8e..41731c8d27 100644
--- a/crates/paths/src/lib.rs
+++ b/crates/paths/src/lib.rs
@@ -271,7 +271,7 @@ impl RelPath {
 /// Taken from <https://github.com/rust-lang/cargo/blob/79c769c3d7b4c2cf6a93781575b7f592ef974255/src/cargo/util/paths.rs#L60-L85>
 fn normalize_path(path: &Path) -> PathBuf {
     let mut components = path.components().peekable();
-    let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() {
+    let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().copied() {
         components.next();
         PathBuf::from(c.as_os_str())
     } else {
diff --git a/crates/proc_macro_api/src/msg/flat.rs b/crates/proc_macro_api/src/msg/flat.rs
index 3201394f7f..8437444e18 100644
--- a/crates/proc_macro_api/src/msg/flat.rs
+++ b/crates/proc_macro_api/src/msg/flat.rs
@@ -246,7 +246,7 @@ impl<'a> Writer<'a> {
 
     fn enqueue(&mut self, subtree: &'a tt::Subtree) -> u32 {
         let idx = self.subtree.len();
-        let delimiter_id = subtree.delimiter.map(|it| it.id).unwrap_or_else(TokenId::unspecified);
+        let delimiter_id = subtree.delimiter.map_or(TokenId::unspecified(), |it| it.id);
         let delimiter_kind = subtree.delimiter.map(|it| it.kind);
         self.subtree.push(SubtreeRepr { id: delimiter_id, kind: delimiter_kind, tt: [!0, !0] });
         self.work.push_back((idx, subtree));
@@ -320,7 +320,7 @@ impl Reader {
                     })
                     .collect(),
             };
-            res[i] = Some(s)
+            res[i] = Some(s);
         }
 
         res[0].take().unwrap()
diff --git a/crates/proc_macro_srv/src/abis/abi_1_47/rustc_server.rs b/crates/proc_macro_srv/src/abis/abi_1_47/rustc_server.rs
index ff4976d0cb..a77433a551 100644
--- a/crates/proc_macro_srv/src/abis/abi_1_47/rustc_server.rs
+++ b/crates/proc_macro_srv/src/abis/abi_1_47/rustc_server.rs
@@ -497,10 +497,9 @@ impl server::Literal for Rustc {
     }
 
     fn integer(&mut self, n: &str) -> Self::Literal {
-        let n = if let Ok(n) = n.parse::<i128>() {
-            n.to_string()
-        } else {
-            n.parse::<u128>().unwrap().to_string()
+        let n = match n.parse::<i128>() {
+            Ok(n) => n.to_string(),
+            Err(_) => n.parse::<u128>().unwrap().to_string(),
         };
         Literal { text: n.into(), id: tt::TokenId::unspecified() }
     }
diff --git a/crates/proc_macro_srv/src/abis/abi_1_55/rustc_server.rs b/crates/proc_macro_srv/src/abis/abi_1_55/rustc_server.rs
index 56f9853399..498fa7ea2d 100644
--- a/crates/proc_macro_srv/src/abis/abi_1_55/rustc_server.rs
+++ b/crates/proc_macro_srv/src/abis/abi_1_55/rustc_server.rs
@@ -500,10 +500,9 @@ impl server::Literal for Rustc {
     }
 
     fn integer(&mut self, n: &str) -> Self::Literal {
-        let n = if let Ok(n) = n.parse::<i128>() {
-            n.to_string()
-        } else {
-            n.parse::<u128>().unwrap().to_string()
+        let n = match n.parse::<i128>() {
+            Ok(n) => n.to_string(),
+            Err(_) => n.parse::<u128>().unwrap().to_string(),
         };
         Literal { text: n.into(), id: tt::TokenId::unspecified() }
     }
diff --git a/crates/proc_macro_srv/src/abis/abi_1_56/rustc_server.rs b/crates/proc_macro_srv/src/abis/abi_1_56/rustc_server.rs
index c1064ae968..fb8a4c8cbe 100644
--- a/crates/proc_macro_srv/src/abis/abi_1_56/rustc_server.rs
+++ b/crates/proc_macro_srv/src/abis/abi_1_56/rustc_server.rs
@@ -504,10 +504,9 @@ impl server::Literal for Rustc {
     }
 
     fn integer(&mut self, n: &str) -> Self::Literal {
-        let n = if let Ok(n) = n.parse::<i128>() {
-            n.to_string()
-        } else {
-            n.parse::<u128>().unwrap().to_string()
+        let n = match n.parse::<i128>() {
+            Ok(n) => n.to_string(),
+            Err(_) => n.parse::<u128>().unwrap().to_string(),
         };
         Literal { text: n.into(), id: tt::TokenId::unspecified() }
     }
diff --git a/crates/profile/src/hprof.rs b/crates/profile/src/hprof.rs
index 3ce11fd86c..b562c193e7 100644
--- a/crates/profile/src/hprof.rs
+++ b/crates/profile/src/hprof.rs
@@ -93,7 +93,7 @@ struct ProfilerImpl {
 impl ProfileSpan {
     pub fn detail(mut self, detail: impl FnOnce() -> String) -> ProfileSpan {
         if let Some(profiler) = &mut self.0 {
-            profiler.detail = Some(detail())
+            profiler.detail = Some(detail());
         }
         self
     }
@@ -114,7 +114,7 @@ impl HeartbeatSpan {
     #[inline]
     pub fn new(enabled: bool) -> Self {
         if enabled {
-            with_profile_stack(|it| it.heartbeats(true))
+            with_profile_stack(|it| it.heartbeats(true));
         }
         Self { enabled }
     }
@@ -123,7 +123,7 @@ impl HeartbeatSpan {
 impl Drop for HeartbeatSpan {
     fn drop(&mut self) {
         if self.enabled {
-            with_profile_stack(|it| it.heartbeats(false))
+            with_profile_stack(|it| it.heartbeats(false));
         }
     }
 }
@@ -238,7 +238,7 @@ impl ProfileStack {
             self.heartbeat(frame.heartbeats);
             let avg_span = duration / (frame.heartbeats + 1);
             if avg_span > self.filter.heartbeat_longer_than {
-                eprintln!("Too few heartbeats {} ({}/{:?})?", label, frame.heartbeats, duration)
+                eprintln!("Too few heartbeats {} ({}/{:?})?", label, frame.heartbeats, duration);
             }
         }
 
@@ -292,7 +292,7 @@ fn print(
         accounted_for += tree[child].duration;
 
         if tree[child].duration.as_millis() > longer_than.as_millis() {
-            print(tree, child, level + 1, longer_than, out)
+            print(tree, child, level + 1, longer_than, out);
         } else {
             let (total_duration, cnt) =
                 short_children.entry(tree[child].label).or_insert((Duration::default(), 0));
@@ -301,7 +301,7 @@ fn print(
         }
     }
 
-    for (child_msg, (duration, count)) in short_children.iter() {
+    for (child_msg, (duration, count)) in &short_children {
         writeln!(out, "    {}{} - {} ({} calls)", current_indent, ms(*duration), child_msg, count)
             .expect("printing profiling info");
     }
diff --git a/crates/profile/src/lib.rs b/crates/profile/src/lib.rs
index 5ea5039dba..c5f6bccca1 100644
--- a/crates/profile/src/lib.rs
+++ b/crates/profile/src/lib.rs
@@ -92,7 +92,7 @@ pub fn cpu_span() -> CpuSpan {
     {
         eprintln!(
             r#"cpu profiling is disabled, uncomment `default = [ "cpu_profiler" ]` in Cargo.toml to enable."#
-        )
+        );
     }
 
     CpuSpan { _private: () }
diff --git a/crates/profile/src/stop_watch.rs b/crates/profile/src/stop_watch.rs
index 112d03a9c7..43b1ce9e6d 100644
--- a/crates/profile/src/stop_watch.rs
+++ b/crates/profile/src/stop_watch.rs
@@ -70,15 +70,15 @@ impl fmt::Display for StopWatchSpan {
             let mut prefix = "";
             if instructions > 10000 {
                 instructions /= 1000;
-                prefix = "k"
+                prefix = "k";
             }
             if instructions > 10000 {
                 instructions /= 1000;
-                prefix = "m"
+                prefix = "m";
             }
             if instructions > 10000 {
                 instructions /= 1000;
-                prefix = "g"
+                prefix = "g";
             }
             write!(f, ", {}{}instr", instructions, prefix)?;
         }
diff --git a/crates/project_model/src/sysroot.rs b/crates/project_model/src/sysroot.rs
index a7a7cb6da0..153cbc1c84 100644
--- a/crates/project_model/src/sysroot.rs
+++ b/crates/project_model/src/sysroot.rs
@@ -188,13 +188,13 @@ fn get_rustc_src(sysroot_path: &AbsPath) -> Option<ManifestPath> {
 }
 
 fn get_rust_src(sysroot_path: &AbsPath) -> Option<AbsPathBuf> {
-    let rust_src = sysroot_path.join("lib/rustlib/src/rust/library");
-    tracing::debug!("Checking sysroot: {}", rust_src.display());
-    if fs::metadata(&rust_src).is_ok() {
-        Some(rust_src)
-    } else {
-        None
-    }
+    // Try the new path first since the old one still exists.
+    let rust_src = sysroot_path.join("lib/rustlib/src/rust");
+    tracing::debug!(
+        "Checking sysroot (looking for `library` and `src` dirs): {}",
+        rust_src.display()
+    );
+    ["library", "src"].iter().map(|it| rust_src.join(it)).find(|it| fs::metadata(it).is_ok())
 }
 
 const SYSROOT_CRATES: &str = "
diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs
index cb79ce08ba..714e2dd301 100644
--- a/crates/project_model/src/workspace.rs
+++ b/crates/project_model/src/workspace.rs
@@ -563,12 +563,11 @@ fn cargo_to_crate_graph(
                     pkg_to_lib_crate.insert(pkg, crate_id);
                 }
                 if let Some(proc_macro) = libproc_macro {
-                    add_dep_with_prelude(
+                    add_dep(
                         &mut crate_graph,
                         crate_id,
                         CrateName::new("proc_macro").unwrap(),
                         proc_macro,
-                        cargo[tgt].is_proc_macro,
                     );
                 }
 
diff --git a/crates/rust-analyzer/build.rs b/crates/rust-analyzer/build.rs
index aceab82d9b..99780343fd 100644
--- a/crates/rust-analyzer/build.rs
+++ b/crates/rust-analyzer/build.rs
@@ -4,7 +4,7 @@ use std::{env, path::PathBuf, process::Command};
 
 fn main() {
     set_rerun();
-    println!("cargo:rustc-env=REV={}", rev())
+    println!("cargo:rustc-env=REV={}", rev());
 }
 
 fn set_rerun() {
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index e62bb9499f..6cb6b0a8d0 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -427,10 +427,9 @@ pub(crate) fn handle_workspace_symbol(
         // If no explicit marker was set, check request params. If that's also empty
         // use global config.
         if !all_symbols {
-            let search_kind = if let Some(ref search_kind) = params.search_kind {
-                search_kind
-            } else {
-                &config.search_kind
+            let search_kind = match params.search_kind {
+                Some(ref search_kind) => search_kind,
+                None => &config.search_kind,
             };
             all_symbols = match search_kind {
                 lsp_ext::WorkspaceSymbolSearchKind::OnlyTypes => false,
@@ -439,10 +438,9 @@ pub(crate) fn handle_workspace_symbol(
         }
 
         if !libs {
-            let search_scope = if let Some(ref search_scope) = params.search_scope {
-                search_scope
-            } else {
-                &config.search_scope
+            let search_scope = match params.search_scope {
+                Some(ref search_scope) => search_scope,
+                None => &config.search_scope,
             };
             libs = match search_scope {
                 lsp_ext::WorkspaceSymbolSearchScope::Workspace => false,
diff --git a/crates/sourcegen/src/lib.rs b/crates/sourcegen/src/lib.rs
index 6a332bce85..398e846a14 100644
--- a/crates/sourcegen/src/lib.rs
+++ b/crates/sourcegen/src/lib.rs
@@ -33,9 +33,9 @@ pub fn list_files(dir: &Path) -> Vec<PathBuf> {
                 path.file_name().unwrap_or_default().to_str().unwrap_or_default().starts_with('.');
             if !is_hidden {
                 if file_type.is_dir() {
-                    work.push(path)
+                    work.push(path);
                 } else if file_type.is_file() {
-                    res.push(path)
+                    res.push(path);
                 }
             }
         }
@@ -66,7 +66,7 @@ impl CommentBlock {
                         panic!(
                             "Use plain (non-doc) comments with tags like {}:\n    {}",
                             tag, first
-                        )
+                        );
                     }
 
                     block.id = id.trim().to_string();
@@ -106,7 +106,7 @@ impl CommentBlock {
             }
         }
         if !block.contents.is_empty() {
-            res.push(block)
+            res.push(block);
         }
         res
     }
@@ -139,7 +139,7 @@ fn ensure_rustfmt() {
         panic!(
             "Failed to run rustfmt from toolchain 'stable'. \
                  Please run `rustup component add rustfmt --toolchain stable` to install it.",
-        )
+        );
     }
 }
 
@@ -185,7 +185,7 @@ pub fn ensure_file_contents(file: &Path, contents: &str) {
         let _ = fs::create_dir_all(parent);
     }
     fs::write(file, contents).unwrap();
-    panic!("some file was not up to date and has been updated, simply re-run the tests")
+    panic!("some file was not up to date and has been updated, simply re-run the tests");
 }
 
 fn normalize_newlines(s: &str) -> String {
diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs
index e7d4753de0..bfa6024679 100644
--- a/crates/stdx/src/lib.rs
+++ b/crates/stdx/src/lib.rs
@@ -45,7 +45,7 @@ fn to_snake_case<F: Fn(&char) -> char>(s: &str, change_case: F) -> String {
         if c.is_ascii_uppercase() && prev {
             // This check is required to not translate `Weird_Case` into `weird__case`.
             if !buf.ends_with('_') {
-                buf.push('_')
+                buf.push('_');
             }
         }
         prev = true;
@@ -60,7 +60,7 @@ pub fn replace(buf: &mut String, from: char, to: &str) {
         return;
     }
     // FIXME: do this in place.
-    *buf = buf.replace(from, to)
+    *buf = buf.replace(from, to);
 }
 
 pub fn trim_indent(mut text: &str) -> String {
@@ -101,7 +101,7 @@ pub fn defer<F: FnOnce()>(f: F) -> impl Drop {
     impl<F: FnOnce()> Drop for D<F> {
         fn drop(&mut self) {
             if let Some(f) = self.0.take() {
-                f()
+                f();
             }
         }
     }
diff --git a/crates/stdx/src/panic_context.rs b/crates/stdx/src/panic_context.rs
index 26debf3c47..f8fafc5a67 100644
--- a/crates/stdx/src/panic_context.rs
+++ b/crates/stdx/src/panic_context.rs
@@ -25,19 +25,19 @@ impl PanicContext {
                 if !ctx.is_empty() {
                     eprintln!("Panic context:");
                     for frame in ctx.iter() {
-                        eprintln!("> {}\n", frame)
+                        eprintln!("> {}\n", frame);
                     }
                 }
-                default_hook(panic_info)
-            })
+                default_hook(panic_info);
+            });
         };
-        panic::set_hook(Box::new(hook))
+        panic::set_hook(Box::new(hook));
     }
 }
 
 impl Drop for PanicContext {
     fn drop(&mut self) {
-        with_ctx(|ctx| assert!(ctx.pop().is_some()))
+        with_ctx(|ctx| assert!(ctx.pop().is_some()));
     }
 }
 
@@ -45,5 +45,5 @@ fn with_ctx(f: impl FnOnce(&mut Vec<String>)) {
     thread_local! {
         static CTX: RefCell<Vec<String>> = RefCell::new(Vec::new());
     }
-    CTX.with(|ctx| f(&mut *ctx.borrow_mut()))
+    CTX.with(|ctx| f(&mut *ctx.borrow_mut()));
 }
diff --git a/crates/stdx/src/process.rs b/crates/stdx/src/process.rs
index b290ba2f05..34cabf7807 100644
--- a/crates/stdx/src/process.rs
+++ b/crates/stdx/src/process.rs
@@ -42,9 +42,9 @@ pub fn streaming_output(
                 };
                 for line in String::from_utf8_lossy(new_lines).lines() {
                     if is_out {
-                        on_stdout_line(line)
+                        on_stdout_line(line);
                     } else {
-                        on_stderr_line(line)
+                        on_stderr_line(line);
                     }
                 }
             }
diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs
index 9c7f93e130..bce02971c6 100644
--- a/crates/syntax/src/algo.rs
+++ b/crates/syntax/src/algo.rs
@@ -112,15 +112,15 @@ impl TreeDiff {
     pub fn into_text_edit(&self, builder: &mut TextEditBuilder) {
         let _p = profile::span("into_text_edit");
 
-        for (anchor, to) in self.insertions.iter() {
+        for (anchor, to) in &self.insertions {
             let offset = match anchor {
                 TreeDiffInsertPos::After(it) => it.text_range().end(),
                 TreeDiffInsertPos::AsFirstChild(it) => it.text_range().start(),
             };
             to.iter().for_each(|to| builder.insert(offset, to.to_string()));
         }
-        for (from, to) in self.replacements.iter() {
-            builder.replace(from.text_range(), to.to_string())
+        for (from, to) in &self.replacements {
+            builder.replace(from.text_range(), to.to_string());
         }
         for text_range in self.deletions.iter().map(SyntaxElement::text_range) {
             builder.delete(text_range);
@@ -217,9 +217,8 @@ pub fn diff(from: &SyntaxNode, to: &SyntaxNode) -> TreeDiff {
                             cov_mark::hit!(diff_insertions);
                             insert = true;
                             break;
-                        } else {
-                            look_ahead_scratch.push(rhs_child);
                         }
+                        look_ahead_scratch.push(rhs_child);
                     }
                     let drain = look_ahead_scratch.drain(..);
                     if insert {
@@ -233,7 +232,7 @@ pub fn diff(from: &SyntaxNode, to: &SyntaxNode) -> TreeDiff {
                         diff.insertions.entry(insert_pos).or_insert_with(Vec::new).extend(drain);
                         rhs_children = rhs_children_clone;
                     } else {
-                        go(diff, lhs_ele, rhs_ele)
+                        go(diff, lhs_ele, rhs_ele);
                     }
                 }
             }
diff --git a/crates/syntax/src/ast.rs b/crates/syntax/src/ast.rs
index 8732593af9..e57c3d2fe4 100644
--- a/crates/syntax/src/ast.rs
+++ b/crates/syntax/src/ast.rs
@@ -18,7 +18,7 @@ use crate::{
 };
 
 pub use self::{
-    expr_ext::{ArrayExprKind, BlockModifier, CallableExpr, ElseBranch, LiteralKind},
+    expr_ext::{ArrayExprKind, BlockModifier, ElseBranch, LiteralKind},
     generated::{nodes::*, tokens::*},
     node_ext::{
         AttrKind, FieldKind, Macro, NameLike, NameOrNameRef, PathSegmentKind, SelfParamKind,
diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs
index 15e99ff0e9..43a9c6756d 100644
--- a/crates/syntax/src/ast/edit.rs
+++ b/crates/syntax/src/ast/edit.rs
@@ -126,7 +126,7 @@ impl IndentLevel {
             if let Some(ws) = ast::Whitespace::cast(token) {
                 if ws.text().contains('\n') {
                     let new_ws = make::tokens::whitespace(&format!("{}{}", ws.syntax(), self));
-                    ted::replace(ws.syntax(), &new_ws)
+                    ted::replace(ws.syntax(), &new_ws);
                 }
             }
         }
@@ -143,7 +143,7 @@ impl IndentLevel {
                     let new_ws = make::tokens::whitespace(
                         &ws.syntax().text().replace(&format!("\n{}", self), "\n"),
                     );
-                    ted::replace(ws.syntax(), &new_ws)
+                    ted::replace(ws.syntax(), &new_ws);
                 }
             }
         }
diff --git a/crates/syntax/src/ast/edit_in_place.rs b/crates/syntax/src/ast/edit_in_place.rs
index d271b5f836..552d6fc1e3 100644
--- a/crates/syntax/src/ast/edit_in_place.rs
+++ b/crates/syntax/src/ast/edit_in_place.rs
@@ -49,7 +49,7 @@ impl GenericParamsOwnerEdit for ast::Fn {
             } else {
                 Position::last_child_of(self.syntax())
             };
-            create_where_clause(position)
+            create_where_clause(position);
         }
         self.where_clause().unwrap()
     }
@@ -60,10 +60,9 @@ impl GenericParamsOwnerEdit for ast::Impl {
         match self.generic_param_list() {
             Some(it) => it,
             None => {
-                let position = if let Some(imp_token) = self.impl_token() {
-                    Position::after(imp_token)
-                } else {
-                    Position::last_child_of(self.syntax())
+                let position = match self.impl_token() {
+                    Some(imp_token) => Position::after(imp_token),
+                    None => Position::last_child_of(self.syntax()),
                 };
                 create_generic_param_list(position)
             }
@@ -72,12 +71,11 @@ impl GenericParamsOwnerEdit for ast::Impl {
 
     fn get_or_create_where_clause(&self) -> ast::WhereClause {
         if self.where_clause().is_none() {
-            let position = if let Some(items) = self.assoc_item_list() {
-                Position::before(items.syntax())
-            } else {
-                Position::last_child_of(self.syntax())
+            let position = match self.assoc_item_list() {
+                Some(items) => Position::before(items.syntax()),
+                None => Position::last_child_of(self.syntax()),
             };
-            create_where_clause(position)
+            create_where_clause(position);
         }
         self.where_clause().unwrap()
     }
@@ -102,12 +100,11 @@ impl GenericParamsOwnerEdit for ast::Trait {
 
     fn get_or_create_where_clause(&self) -> ast::WhereClause {
         if self.where_clause().is_none() {
-            let position = if let Some(items) = self.assoc_item_list() {
-                Position::before(items.syntax())
-            } else {
-                Position::last_child_of(self.syntax())
+            let position = match self.assoc_item_list() {
+                Some(items) => Position::before(items.syntax()),
+                None => Position::last_child_of(self.syntax()),
             };
-            create_where_clause(position)
+            create_where_clause(position);
         }
         self.where_clause().unwrap()
     }
@@ -145,7 +142,7 @@ impl GenericParamsOwnerEdit for ast::Struct {
             } else {
                 Position::last_child_of(self.syntax())
             };
-            create_where_clause(position)
+            create_where_clause(position);
         }
         self.where_clause().unwrap()
     }
@@ -177,7 +174,7 @@ impl GenericParamsOwnerEdit for ast::Enum {
             } else {
                 Position::last_child_of(self.syntax())
             };
-            create_where_clause(position)
+            create_where_clause(position);
         }
         self.where_clause().unwrap()
     }
@@ -234,7 +231,7 @@ impl ast::GenericParamList {
             }
             None => {
                 let after_l_angle = Position::after(self.l_angle_token().unwrap());
-                ted::insert(after_l_angle, generic_param.syntax())
+                ted::insert(after_l_angle, generic_param.syntax());
             }
         }
     }
@@ -247,18 +244,15 @@ impl ast::WhereClause {
                 ted::append_child_raw(self.syntax(), make::token(T![,]));
             }
         }
-        ted::append_child(self.syntax(), predicate.syntax())
+        ted::append_child(self.syntax(), predicate.syntax());
     }
 }
 
 impl ast::TypeBoundList {
     pub fn remove(&self) {
-        if let Some(colon) =
-            self.syntax().siblings_with_tokens(Direction::Prev).find(|it| it.kind() == T![:])
-        {
-            ted::remove_all(colon..=self.syntax().clone().into())
-        } else {
-            ted::remove(self.syntax())
+        match self.syntax().siblings_with_tokens(Direction::Prev).find(|it| it.kind() == T![:]) {
+            Some(colon) => ted::remove_all(colon..=self.syntax().clone().into()),
+            None => ted::remove(self.syntax()),
         }
     }
 }
@@ -267,7 +261,7 @@ impl ast::PathSegment {
     pub fn get_or_create_generic_arg_list(&self) -> ast::GenericArgList {
         if self.generic_arg_list().is_none() {
             let arg_list = make::generic_arg_list().clone_for_update();
-            ted::append_child(self.syntax(), arg_list.syntax())
+            ted::append_child(self.syntax(), arg_list.syntax());
         }
         self.generic_arg_list().unwrap()
     }
@@ -275,7 +269,7 @@ impl ast::PathSegment {
 
 impl ast::UseTree {
     pub fn remove(&self) {
-        for &dir in [Direction::Next, Direction::Prev].iter() {
+        for dir in [Direction::Next, Direction::Prev] {
             if let Some(next_use_tree) = neighbor(self, dir) {
                 let separators = self
                     .syntax()
@@ -286,7 +280,7 @@ impl ast::UseTree {
                 break;
             }
         }
-        ted::remove(self.syntax())
+        ted::remove(self.syntax());
     }
 }
 
@@ -301,13 +295,13 @@ impl ast::Use {
             let ws_text = next_ws.syntax().text();
             if let Some(rest) = ws_text.strip_prefix('\n') {
                 if rest.is_empty() {
-                    ted::remove(next_ws.syntax())
+                    ted::remove(next_ws.syntax());
                 } else {
-                    ted::replace(next_ws.syntax(), make::tokens::whitespace(rest))
+                    ted::replace(next_ws.syntax(), make::tokens::whitespace(rest));
                 }
             }
         }
-        ted::remove(self.syntax())
+        ted::remove(self.syntax());
     }
 }
 
@@ -455,7 +449,7 @@ impl ast::RecordExprField {
     /// This will either replace the initializer, or in the case that this is a shorthand convert
     /// the initializer into the name ref and insert the expr as the new initializer.
     pub fn replace_expr(&self, expr: ast::Expr) {
-        if let Some(_) = self.name_ref() {
+        if self.name_ref().is_some() {
             match self.expr() {
                 Some(prev) => ted::replace(prev.syntax(), expr.syntax()),
                 None => ted::append_child(self.syntax(), expr.syntax()),
@@ -525,7 +519,7 @@ pub trait Indent: AstNode + Clone + Sized {
     fn reindent_to(&self, target_level: IndentLevel) {
         let current_level = IndentLevel::from_node(self.syntax());
         self.dedent(current_level);
-        self.indent(target_level)
+        self.indent(target_level);
     }
 }
 
diff --git a/crates/syntax/src/ast/expr_ext.rs b/crates/syntax/src/ast/expr_ext.rs
index f421f34b3d..7363ad905a 100644
--- a/crates/syntax/src/ast/expr_ext.rs
+++ b/crates/syntax/src/ast/expr_ext.rs
@@ -10,7 +10,7 @@ use crate::{
     },
     AstToken,
     SyntaxKind::*,
-    SyntaxNode, SyntaxToken, T,
+    SyntaxToken, T,
 };
 
 impl ast::HasAttrs for ast::Expr {}
@@ -312,41 +312,3 @@ impl ast::RecordExprField {
         self.syntax().ancestors().find_map(ast::RecordExpr::cast).unwrap()
     }
 }
-
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum CallableExpr {
-    Call(ast::CallExpr),
-    MethodCall(ast::MethodCallExpr),
-}
-
-impl ast::HasAttrs for CallableExpr {}
-impl ast::HasArgList for CallableExpr {}
-
-impl AstNode for CallableExpr {
-    fn can_cast(kind: parser::SyntaxKind) -> bool
-    where
-        Self: Sized,
-    {
-        ast::CallExpr::can_cast(kind) || ast::MethodCallExpr::can_cast(kind)
-    }
-
-    fn cast(syntax: SyntaxNode) -> Option<Self>
-    where
-        Self: Sized,
-    {
-        if let Some(it) = ast::CallExpr::cast(syntax.clone()) {
-            Some(Self::Call(it))
-        } else if let Some(it) = ast::MethodCallExpr::cast(syntax.clone()) {
-            Some(Self::MethodCall(it))
-        } else {
-            None
-        }
-    }
-
-    fn syntax(&self) -> &SyntaxNode {
-        match self {
-            Self::Call(it) => it.syntax(),
-            Self::MethodCall(it) => it.syntax(),
-        }
-    }
-}
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs
index 40c0cd7a37..d1888d165c 100644
--- a/crates/syntax/src/ast/make.rs
+++ b/crates/syntax/src/ast/make.rs
@@ -257,7 +257,7 @@ pub fn block_expr(
         format_to!(buf, "    {}\n", stmt);
     }
     if let Some(tail_expr) = tail_expr {
-        format_to!(buf, "    {}\n", tail_expr)
+        format_to!(buf, "    {}\n", tail_expr);
     }
     buf += "}";
     ast_from_text(&format!("fn f() {}", buf))
@@ -299,9 +299,6 @@ pub fn expr_return(expr: Option<ast::Expr>) -> ast::Expr {
 pub fn expr_try(expr: ast::Expr) -> ast::Expr {
     expr_from_text(&format!("{}?", expr))
 }
-pub fn expr_await(expr: ast::Expr) -> ast::Expr {
-    expr_from_text(&format!("{}.await", expr))
-}
 pub fn expr_match(expr: ast::Expr, match_arm_list: ast::MatchArmList) -> ast::Expr {
     expr_from_text(&format!("match {} {}", expr, match_arm_list))
 }
@@ -644,9 +641,14 @@ pub fn fn_(
     ret_type: Option<ast::RetType>,
     is_async: bool,
 ) -> ast::Fn {
-    let type_params =
-        if let Some(type_params) = type_params { format!("<{}>", type_params) } else { "".into() };
-    let ret_type = if let Some(ret_type) = ret_type { format!("{} ", ret_type) } else { "".into() };
+    let type_params = match type_params {
+        Some(type_params) => format!("<{}>", type_params),
+        None => "".into(),
+    };
+    let ret_type = match ret_type {
+        Some(ret_type) => format!("{} ", ret_type),
+        None => "".into(),
+    };
     let visibility = match visibility {
         None => String::new(),
         Some(it) => format!("{} ", it),
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index 800befb04b..2e6544f090 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -276,9 +276,9 @@ impl ast::Path {
 
 impl ast::Use {
     pub fn is_simple_glob(&self) -> bool {
-        self.use_tree()
-            .map(|use_tree| use_tree.use_tree_list().is_none() && use_tree.star_token().is_some())
-            .unwrap_or(false)
+        self.use_tree().map_or(false, |use_tree| {
+            use_tree.use_tree_list().is_none() && use_tree.star_token().is_some()
+        })
     }
 }
 
@@ -549,10 +549,9 @@ impl ast::FieldExpr {
     }
 
     pub fn field_access(&self) -> Option<FieldKind> {
-        if let Some(nr) = self.name_ref() {
-            Some(FieldKind::Name(nr))
-        } else {
-            self.index_token().map(FieldKind::Index)
+        match self.name_ref() {
+            Some(nr) => Some(FieldKind::Name(nr)),
+            None => self.index_token().map(FieldKind::Index),
         }
     }
 }
diff --git a/crates/syntax/src/ast/token_ext.rs b/crates/syntax/src/ast/token_ext.rs
index ad52d9f540..2f8312d5d1 100644
--- a/crates/syntax/src/ast/token_ext.rs
+++ b/crates/syntax/src/ast/token_ext.rs
@@ -283,10 +283,9 @@ pub trait HasFormatSpecifier: AstToken {
     where
         F: FnMut(TextRange, FormatSpecifier),
     {
-        let char_ranges = if let Some(char_ranges) = self.char_ranges() {
-            char_ranges
-        } else {
-            return;
+        let char_ranges = match self.char_ranges() {
+            Some(char_ranges) => char_ranges,
+            None => return,
         };
         let mut chars = char_ranges.iter().peekable();
 
@@ -528,10 +527,11 @@ pub trait HasFormatSpecifier: AstToken {
                         }
                     }
 
-                    if let Some((_, Ok('}'))) = chars.peek() {
-                        skip_char_and_emit(&mut chars, FormatSpecifier::Close, &mut callback);
-                    } else {
-                        continue;
+                    match chars.peek() {
+                        Some((_, Ok('}'))) => {
+                            skip_char_and_emit(&mut chars, FormatSpecifier::Close, &mut callback);
+                        }
+                        Some((_, _)) | None => continue,
                     }
                 }
                 _ => {
@@ -609,7 +609,7 @@ impl HasFormatSpecifier for ast::String {
                 TextRange::new(range.start.try_into().unwrap(), range.end.try_into().unwrap())
                     + offset,
                 unescaped_char,
-            ))
+            ));
         });
 
         Some(res)
@@ -631,7 +631,7 @@ impl ast::IntNumber {
 
         let mut text = token.text();
         if let Some(suffix) = self.suffix() {
-            text = &text[..text.len() - suffix.len()]
+            text = &text[..text.len() - suffix.len()];
         }
 
         let radix = self.radix();
@@ -688,7 +688,7 @@ impl Radix {
     pub const ALL: &'static [Radix] =
         &[Radix::Binary, Radix::Octal, Radix::Decimal, Radix::Hexadecimal];
 
-    const fn prefix_len(&self) -> usize {
+    const fn prefix_len(self) -> usize {
         match self {
             Self::Decimal => 0,
             _ => 2,
diff --git a/crates/syntax/src/display.rs b/crates/syntax/src/display.rs
index 1498385fef..95e37944cc 100644
--- a/crates/syntax/src/display.rs
+++ b/crates/syntax/src/display.rs
@@ -28,7 +28,7 @@ pub fn function_declaration(node: &ast::Fn) -> String {
         format_to!(buf, "{} ", abi);
     }
     if let Some(name) = node.name() {
-        format_to!(buf, "fn {}", name)
+        format_to!(buf, "fn {}", name);
     }
     if let Some(type_params) = node.generic_param_list() {
         format_to!(buf, "{}", type_params);
diff --git a/crates/syntax/src/parsing/text_token_source.rs b/crates/syntax/src/parsing/text_token_source.rs
index 0614194a56..11dfc63a65 100644
--- a/crates/syntax/src/parsing/text_token_source.rs
+++ b/crates/syntax/src/parsing/text_token_source.rs
@@ -44,8 +44,7 @@ impl<'t> TokenSource for TextTokenSource<'t> {
     fn is_keyword(&self, kw: &str) -> bool {
         self.token_offset_pairs
             .get(self.curr.1)
-            .map(|(token, offset)| &self.text[TextRange::at(*offset, token.len)] == kw)
-            .unwrap_or(false)
+            .map_or(false, |(token, offset)| &self.text[TextRange::at(*offset, token.len)] == kw)
     }
 }
 
@@ -55,8 +54,7 @@ fn mk_token(pos: usize, token_offset_pairs: &[(Token, TextSize)]) -> parser::Tok
             token.kind,
             token_offset_pairs
                 .get(pos + 1)
-                .map(|(_, next_offset)| offset + token.len == *next_offset)
-                .unwrap_or(false),
+                .map_or(false, |(_, next_offset)| offset + token.len == *next_offset),
         ),
         None => (EOF, false),
     };
diff --git a/crates/syntax/src/parsing/text_tree_sink.rs b/crates/syntax/src/parsing/text_tree_sink.rs
index 25bfd41a16..8c1de92048 100644
--- a/crates/syntax/src/parsing/text_tree_sink.rs
+++ b/crates/syntax/src/parsing/text_tree_sink.rs
@@ -88,7 +88,7 @@ impl<'a> TreeSink for TextTreeSink<'a> {
     }
 
     fn error(&mut self, error: ParseError) {
-        self.inner.error(error, self.text_pos)
+        self.inner.error(error, self.text_pos);
     }
 }
 
@@ -108,7 +108,7 @@ impl<'a> TextTreeSink<'a> {
         match mem::replace(&mut self.state, State::Normal) {
             State::PendingFinish => {
                 self.eat_trivias();
-                self.inner.finish_node()
+                self.inner.finish_node();
             }
             State::PendingStart | State::Normal => unreachable!(),
         }
diff --git a/crates/syntax/src/ptr.rs b/crates/syntax/src/ptr.rs
index 282470bae4..57ae64cafe 100644
--- a/crates/syntax/src/ptr.rs
+++ b/crates/syntax/src/ptr.rs
@@ -81,7 +81,7 @@ impl<N: AstNode> PartialEq for AstPtr<N> {
 
 impl<N: AstNode> Hash for AstPtr<N> {
     fn hash<H: Hasher>(&self, state: &mut H) {
-        self.raw.hash(state)
+        self.raw.hash(state);
     }
 }
 
diff --git a/crates/syntax/src/syntax_node.rs b/crates/syntax/src/syntax_node.rs
index 0ddfd439dc..bd7ea0240b 100644
--- a/crates/syntax/src/syntax_node.rs
+++ b/crates/syntax/src/syntax_node.rs
@@ -56,19 +56,19 @@ impl SyntaxTreeBuilder {
 
     pub fn token(&mut self, kind: SyntaxKind, text: &str) {
         let kind = RustLanguage::kind_to_raw(kind);
-        self.inner.token(kind, text)
+        self.inner.token(kind, text);
     }
 
     pub fn start_node(&mut self, kind: SyntaxKind) {
         let kind = RustLanguage::kind_to_raw(kind);
-        self.inner.start_node(kind)
+        self.inner.start_node(kind);
     }
 
     pub fn finish_node(&mut self) {
-        self.inner.finish_node()
+        self.inner.finish_node();
     }
 
     pub fn error(&mut self, error: parser::ParseError, text_pos: TextSize) {
-        self.errors.push(SyntaxError::new_at_offset(*error.0, text_pos))
+        self.errors.push(SyntaxError::new_at_offset(*error.0, text_pos));
     }
 }
diff --git a/crates/syntax/src/ted.rs b/crates/syntax/src/ted.rs
index 4b0d8bf391..a47b4b11c0 100644
--- a/crates/syntax/src/ted.rs
+++ b/crates/syntax/src/ted.rs
@@ -77,23 +77,23 @@ impl Position {
 }
 
 pub fn insert(position: Position, elem: impl Element) {
-    insert_all(position, vec![elem.syntax_element()])
+    insert_all(position, vec![elem.syntax_element()]);
 }
 pub fn insert_raw(position: Position, elem: impl Element) {
-    insert_all_raw(position, vec![elem.syntax_element()])
+    insert_all_raw(position, vec![elem.syntax_element()]);
 }
 pub fn insert_all(position: Position, mut elements: Vec<SyntaxElement>) {
     if let Some(first) = elements.first() {
         if let Some(ws) = ws_before(&position, first) {
-            elements.insert(0, ws.into())
+            elements.insert(0, ws.into());
         }
     }
     if let Some(last) = elements.last() {
         if let Some(ws) = ws_after(&position, last) {
-            elements.push(ws.into())
+            elements.push(ws.into());
         }
     }
-    insert_all_raw(position, elements)
+    insert_all_raw(position, elements);
 }
 pub fn insert_all_raw(position: Position, elements: Vec<SyntaxElement>) {
     let (parent, index) = match position.repr {
@@ -104,10 +104,10 @@ pub fn insert_all_raw(position: Position, elements: Vec<SyntaxElement>) {
 }
 
 pub fn remove(elem: impl Element) {
-    elem.syntax_element().detach()
+    elem.syntax_element().detach();
 }
 pub fn remove_all(range: RangeInclusive<SyntaxElement>) {
-    replace_all(range, Vec::new())
+    replace_all(range, Vec::new());
 }
 pub fn remove_all_iter(range: impl IntoIterator<Item = SyntaxElement>) {
     let mut it = range.into_iter();
@@ -115,9 +115,9 @@ pub fn remove_all_iter(range: impl IntoIterator<Item = SyntaxElement>) {
         match it.last() {
             Some(mut last) => {
                 if first.index() > last.index() {
-                    mem::swap(&mut first, &mut last)
+                    mem::swap(&mut first, &mut last);
                 }
-                remove_all(first..=last)
+                remove_all(first..=last);
             }
             None => remove(first),
         }
@@ -125,26 +125,26 @@ pub fn remove_all_iter(range: impl IntoIterator<Item = SyntaxElement>) {
 }
 
 pub fn replace(old: impl Element, new: impl Element) {
-    replace_with_many(old, vec![new.syntax_element()])
+    replace_with_many(old, vec![new.syntax_element()]);
 }
 pub fn replace_with_many(old: impl Element, new: Vec<SyntaxElement>) {
     let old = old.syntax_element();
-    replace_all(old.clone()..=old, new)
+    replace_all(old.clone()..=old, new);
 }
 pub fn replace_all(range: RangeInclusive<SyntaxElement>, new: Vec<SyntaxElement>) {
     let start = range.start().index();
     let end = range.end().index();
     let parent = range.start().parent().unwrap();
-    parent.splice_children(start..end + 1, new)
+    parent.splice_children(start..end + 1, new);
 }
 
 pub fn append_child(node: &(impl Into<SyntaxNode> + Clone), child: impl Element) {
     let position = Position::last_child_of(node);
-    insert(position, child)
+    insert(position, child);
 }
 pub fn append_child_raw(node: &(impl Into<SyntaxNode> + Clone), child: impl Element) {
     let position = Position::last_child_of(node);
-    insert_raw(position, child)
+    insert_raw(position, child);
 }
 
 fn ws_before(position: &Position, new: &SyntaxElement) -> Option<SyntaxToken> {
diff --git a/crates/syntax/src/validation.rs b/crates/syntax/src/validation.rs
index b2d42f6651..521ffce20e 100644
--- a/crates/syntax/src/validation.rs
+++ b/crates/syntax/src/validation.rs
@@ -137,7 +137,7 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) {
                         if let Err(err) = char {
                             push_err(1, (range.start, err));
                         }
-                    })
+                    });
                 }
             }
         }
@@ -148,7 +148,7 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) {
                         if let Err(err) = char {
                             push_err(2, (range.start, err));
                         }
-                    })
+                    });
                 }
             }
         }
diff --git a/crates/syntax/src/validation/block.rs b/crates/syntax/src/validation/block.rs
index 9076b82503..8eb4a10a3f 100644
--- a/crates/syntax/src/validation/block.rs
+++ b/crates/syntax/src/validation/block.rs
@@ -19,6 +19,6 @@ pub(crate) fn validate_block_expr(block: ast::BlockExpr, errors: &mut Vec<Syntax
                 "A block in this position cannot accept inner attributes",
                 attr.syntax().text_range(),
             )
-        }))
+        }));
     }
 }
diff --git a/crates/text_edit/src/lib.rs b/crates/text_edit/src/lib.rs
index a43ffe202f..e9700c560a 100644
--- a/crates/text_edit/src/lib.rs
+++ b/crates/text_edit/src/lib.rs
@@ -90,13 +90,13 @@ impl TextEdit {
         }
 
         let mut total_len = TextSize::of(&*text);
-        for indel in self.indels.iter() {
+        for indel in &self.indels {
             total_len += TextSize::of(&indel.insert);
             total_len -= indel.delete.end() - indel.delete.start();
         }
         let mut buf = String::with_capacity(total_len.into());
         let mut prev = 0;
-        for indel in self.indels.iter() {
+        for indel in &self.indels {
             let start: usize = indel.delete.start().into();
             let end: usize = indel.delete.end().into();
             if start > prev {
@@ -110,7 +110,7 @@ impl TextEdit {
 
         // FIXME: figure out a way to mutate the text in-place or reuse the
         // memory in some other way
-        *text = buf
+        *text = buf;
     }
 
     pub fn union(&mut self, other: TextEdit) -> Result<(), TextEdit> {
@@ -126,7 +126,7 @@ impl TextEdit {
 
     pub fn apply_to_offset(&self, offset: TextSize) -> Option<TextSize> {
         let mut res = offset;
-        for indel in self.indels.iter() {
+        for indel in &self.indels {
             if indel.delete.start() >= offset {
                 break;
             }
@@ -163,13 +163,13 @@ impl TextEditBuilder {
         self.indels.is_empty()
     }
     pub fn replace(&mut self, range: TextRange, replace_with: String) {
-        self.indel(Indel::replace(range, replace_with))
+        self.indel(Indel::replace(range, replace_with));
     }
     pub fn delete(&mut self, range: TextRange) {
-        self.indel(Indel::delete(range))
+        self.indel(Indel::delete(range));
     }
     pub fn insert(&mut self, offset: TextSize, text: String) {
-        self.indel(Indel::insert(offset, text))
+        self.indel(Indel::insert(offset, text));
     }
     pub fn finish(self) -> TextEdit {
         let mut indels = self.indels;
diff --git a/crates/tt/src/buffer.rs b/crates/tt/src/buffer.rs
index dc577700fd..1fa61c41dd 100644
--- a/crates/tt/src/buffer.rs
+++ b/crates/tt/src/buffer.rs
@@ -194,8 +194,7 @@ impl<'a> Cursor<'a> {
                 TokenTree::Subtree(subtree) => Some(TokenTreeRef::Subtree(subtree, Some(tt))),
             },
             Some(Entry::Subtree(tt, subtree, _)) => Some(TokenTreeRef::Subtree(subtree, *tt)),
-            Some(Entry::End(_)) => None,
-            None => None,
+            Some(Entry::End(_)) | None => None,
         }
     }
 
@@ -206,10 +205,9 @@ impl<'a> Cursor<'a> {
     /// Bump the cursor
     pub fn bump(self) -> Cursor<'a> {
         if let Some(Entry::End(exit)) = self.buffer.entry(&self.ptr) {
-            if let Some(exit) = exit {
-                Cursor::create(self.buffer, *exit)
-            } else {
-                self
+            match exit {
+                Some(exit) => Cursor::create(self.buffer, *exit),
+                None => self,
             }
         } else {
             Cursor::create(self.buffer, EntryPtr(self.ptr.0, self.ptr.1 + 1))
diff --git a/crates/tt/src/lib.rs b/crates/tt/src/lib.rs
index 66180bb156..9eca970ee2 100644
--- a/crates/tt/src/lib.rs
+++ b/crates/tt/src/lib.rs
@@ -161,7 +161,7 @@ impl fmt::Display for Subtree {
         };
         f.write_str(l)?;
         let mut needs_space = false;
-        for tt in self.token_trees.iter() {
+        for tt in &self.token_trees {
             if needs_space {
                 f.write_str(" ")?;
             }
@@ -169,7 +169,7 @@ impl fmt::Display for Subtree {
             match tt {
                 TokenTree::Leaf(Leaf::Punct(p)) => {
                     needs_space = p.spacing == Spacing::Alone;
-                    fmt::Display::fmt(p, f)?
+                    fmt::Display::fmt(p, f)?;
                 }
                 tt => fmt::Display::fmt(tt, f)?,
             }
@@ -215,7 +215,7 @@ impl Subtree {
             .iter()
             .map(|c| match c {
                 TokenTree::Subtree(c) => c.count(),
-                _ => 0,
+                TokenTree::Leaf(_) => 0,
             })
             .sum::<usize>();
 
diff --git a/crates/vfs-notify/src/lib.rs b/crates/vfs-notify/src/lib.rs
index 4fb34aed07..a2a53cdc9e 100644
--- a/crates/vfs-notify/src/lib.rs
+++ b/crates/vfs-notify/src/lib.rs
@@ -38,7 +38,7 @@ impl loader::Handle for NotifyHandle {
         NotifyHandle { sender, _thread: thread }
     }
     fn set_config(&mut self, config: loader::Config) {
-        self.sender.send(Message::Config(config)).unwrap()
+        self.sender.send(Message::Config(config)).unwrap();
     }
     fn invalidate(&mut self, path: AbsPathBuf) {
         self.sender.send(Message::Invalidate(path)).unwrap();
@@ -84,7 +84,7 @@ impl NotifyActor {
                         if !config.watch.is_empty() {
                             let (watcher_sender, watcher_receiver) = unbounded();
                             let watcher = log_notify_error(RecommendedWatcher::new(move |event| {
-                                watcher_sender.send(event).unwrap()
+                                watcher_sender.send(event).unwrap();
                             }));
                             self.watcher = watcher.map(|it| (it, watcher_receiver));
                         }
@@ -99,7 +99,7 @@ impl NotifyActor {
                         for (i, entry) in config.load.into_iter().enumerate() {
                             let watch = config.watch.contains(&i);
                             if watch {
-                                self.watched_entries.push(entry.clone())
+                                self.watched_entries.push(entry.clone());
                             }
                             let files = self.load_entry(entry, watch);
                             self.send(loader::Message::Loaded { files });
@@ -149,7 +149,7 @@ impl NotifyActor {
                                 Some((path, contents))
                             })
                             .collect();
-                        self.send(loader::Message::Loaded { files })
+                        self.send(loader::Message::Loaded { files });
                     }
                 }
             }
@@ -165,7 +165,7 @@ impl NotifyActor {
                 .into_iter()
                 .map(|file| {
                     if watch {
-                        self.watch(file.clone())
+                        self.watch(file.clone());
                     }
                     let contents = read(file.as_path());
                     (file, contents)
@@ -174,7 +174,7 @@ impl NotifyActor {
             loader::Entry::Directories(dirs) => {
                 let mut res = Vec::new();
 
-                for root in dirs.include.iter() {
+                for root in &dirs.include {
                     let walkdir =
                         WalkDir::new(root).follow_links(true).into_iter().filter_entry(|entry| {
                             if !entry.file_type().is_dir() {
@@ -218,7 +218,7 @@ impl NotifyActor {
         }
     }
     fn send(&mut self, msg: loader::Message) {
-        (self.sender)(msg)
+        (self.sender)(msg);
     }
 }
 
diff --git a/crates/vfs/src/file_set.rs b/crates/vfs/src/file_set.rs
index 0011f73c96..6a89263e53 100644
--- a/crates/vfs/src/file_set.rs
+++ b/crates/vfs/src/file_set.rs
@@ -112,7 +112,7 @@ impl FileSetConfig {
         let mut res = vec![FileSet::default(); self.len()];
         for (file_id, path) in vfs.iter() {
             let root = self.classify(path, &mut scratch_space);
-            res[root].insert(file_id, path.clone())
+            res[root].insert(file_id, path.clone());
         }
         res
     }
@@ -157,7 +157,7 @@ impl FileSetConfigBuilder {
 
     /// Add a new set of paths prefixes.
     pub fn add_file_set(&mut self, roots: Vec<VfsPath>) {
-        self.roots.push(roots)
+        self.roots.push(roots);
     }
 
     /// Build the `FileSetConfig`.
diff --git a/crates/vfs/src/vfs_path.rs b/crates/vfs/src/vfs_path.rs
index ffd673573a..39a1666421 100644
--- a/crates/vfs/src/vfs_path.rs
+++ b/crates/vfs/src/vfs_path.rs
@@ -73,9 +73,8 @@ impl VfsPath {
     pub fn starts_with(&self, other: &VfsPath) -> bool {
         match (&self.0, &other.0) {
             (VfsPathRepr::PathBuf(lhs), VfsPathRepr::PathBuf(rhs)) => lhs.starts_with(rhs),
-            (VfsPathRepr::PathBuf(_), _) => false,
             (VfsPathRepr::VirtualPath(lhs), VfsPathRepr::VirtualPath(rhs)) => lhs.starts_with(rhs),
-            (VfsPathRepr::VirtualPath(_), _) => false,
+            (VfsPathRepr::PathBuf(_) | VfsPathRepr::VirtualPath(_), _) => false,
         }
     }
 
@@ -357,7 +356,7 @@ impl VirtualPath {
             if !res.pop() {
                 return None;
             }
-            path = &path["../".len()..]
+            path = &path["../".len()..];
         }
         path = path.trim_start_matches("./");
         res.0 = format!("{}/{}", res.0, path);
diff --git a/editors/code/package.json b/editors/code/package.json
index 4ca93b17bc..5f38d1c126 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -65,8 +65,7 @@
         "onCommand:rust-analyzer.analyzerStatus",
         "onCommand:rust-analyzer.memoryUsage",
         "onCommand:rust-analyzer.reloadWorkspace",
-        "workspaceContains:*/Cargo.toml",
-        "workspaceContains:*/rust-project.json"
+        "workspaceContains:**/Cargo.toml"
     ],
     "main": "./out/main",
     "contributes": {
diff --git a/lib/arena/src/lib.rs b/lib/arena/src/lib.rs
index 1720537cb6..162d556fb7 100644
--- a/lib/arena/src/lib.rs
+++ b/lib/arena/src/lib.rs
@@ -63,7 +63,7 @@ impl<T> Eq for Idx<T> {}
 
 impl<T> Hash for Idx<T> {
     fn hash<H: Hasher>(&self, state: &mut H) {
-        self.raw.hash(state)
+        self.raw.hash(state);
     }
 }
 
@@ -71,7 +71,7 @@ impl<T> fmt::Debug for Idx<T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let mut type_name = std::any::type_name::<T>();
         if let Some(idx) = type_name.rfind(':') {
-            type_name = &type_name[idx + 1..]
+            type_name = &type_name[idx + 1..];
         }
         write!(f, "Idx::<{}>({})", type_name, self.raw)
     }
diff --git a/xtask/src/install.rs b/xtask/src/install.rs
index 922957f57d..d026df6c15 100644
--- a/xtask/src/install.rs
+++ b/xtask/src/install.rs
@@ -13,7 +13,7 @@ const REQUIRED_RUST_VERSION: u32 = 55;
 impl flags::Install {
     pub(crate) fn run(self) -> Result<()> {
         if cfg!(target_os = "macos") {
-            fix_path_for_mac().context("Fix path for mac")?
+            fix_path_for_mac().context("Fix path for mac")?;
         }
         if let Some(server) = self.server() {
             install_server(server).context("install server")?;
@@ -148,7 +148,7 @@ fn install_server(opts: ServerOpt) -> Result<()> {
         eprintln!(
             "\nWARNING: at least rust 1.{}.0 is required to compile rust-analyzer\n",
             REQUIRED_RUST_VERSION,
-        )
+        );
     }
     let features = match opts.malloc {
         Malloc::System => &[][..],
diff --git a/xtask/src/release.rs b/xtask/src/release.rs
index e4f540d27f..d0ddf27b4d 100644
--- a/xtask/src/release.rs
+++ b/xtask/src/release.rs
@@ -33,15 +33,13 @@ impl flags::Release {
         let commit = cmd!("git rev-parse HEAD").read()?;
         let changelog_n = read_dir(changelog_dir.as_path())?.len();
 
-        for &adoc in [
+        for adoc in [
             "manual.adoc",
             "generated_assists.adoc",
             "generated_config.adoc",
             "generated_diagnostic.adoc",
             "generated_features.adoc",
-        ]
-        .iter()
-        {
+        ] {
             let src = project_root().join("./docs/user/").join(adoc);
             let dst = website_root.join(adoc);
 


Test patch:
diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs
index cf6833e56a..29250dca00 100644
--- a/crates/hir_ty/src/tests.rs
+++ b/crates/hir_ty/src/tests.rs
@@ -195,10 +195,9 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
                 mismatch.expected.display_test(&db),
                 mismatch.actual.display_test(&db)
             );
-            if let Some(annotation) = mismatches.remove(&range) {
-                assert_eq!(actual, annotation);
-            } else {
-                format_to!(unexpected_type_mismatches, "{:?}: {}\n", range.range, actual);
+            match mismatches.remove(&range) {
+                Some(annotation) => assert_eq!(actual, annotation),
+                None => format_to!(unexpected_type_mismatches, "{:?}: {}\n", range.range, actual),
             }
         }
         for (expr, mismatch) in inference_result.expr_type_mismatches() {
@@ -215,10 +214,9 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
                 mismatch.expected.display_test(&db),
                 mismatch.actual.display_test(&db)
             );
-            if let Some(annotation) = mismatches.remove(&range) {
-                assert_eq!(actual, annotation);
-            } else {
-                format_to!(unexpected_type_mismatches, "{:?}: {}\n", range.range, actual);
+            match mismatches.remove(&range) {
+                Some(annotation) => assert_eq!(actual, annotation),
+                None => format_to!(unexpected_type_mismatches, "{:?}: {}\n", range.range, actual),
             }
         }
     }
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index 9531be760e..2e074410cd 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -2100,8 +2100,7 @@ fn test() {
 
 #[test]
 fn unselected_projection_in_trait_env_cycle_1() {
-    // This is not a cycle, because the `T: Trait2<T::Item>` bound depends only on the `T: Trait`
-    // bound, not on itself (since only `Trait` can define `Item`).
+    // this is a legitimate cycle
     check_types(
         r#"
 trait Trait {
@@ -2112,7 +2111,7 @@ trait Trait2<T> {}
 
 fn test<T: Trait>() where T: Trait2<T::Item> {
     let x: T::Item = no_matter;
-}                  //^^^^^^^^^ Trait::Item<T>
+}                  //^^^^^^^^^ {unknown}
 "#,
     );
 }
diff --git a/crates/ide_db/src/call_info/tests.rs b/crates/ide_db/src/call_info/tests.rs
index 8cdfcd027a..b585085f38 100644
--- a/crates/ide_db/src/call_info/tests.rs
+++ b/crates/ide_db/src/call_info/tests.rs
@@ -362,6 +362,7 @@ pub fn foo(mut r: WriteHandler<()>) {
 
 #[test]
 fn call_info_bad_offset() {
+    cov_mark::check!(call_info_bad_offset);
     check(
         r#"
 fn foo(x: u32, y: u32) -> u32 {x + y}
diff --git a/crates/ide_db/src/helpers/insert_use/tests.rs b/crates/ide_db/src/helpers/insert_use/tests.rs
index f3b9c7130f..339360ba4a 100644
--- a/crates/ide_db/src/helpers/insert_use/tests.rs
+++ b/crates/ide_db/src/helpers/insert_use/tests.rs
@@ -612,7 +612,6 @@ fn merge_mod_into_glob() {
 
 #[test]
 fn merge_self_glob() {
-    cov_mark::check!(merge_self_glob);
     check_with_config(
         "self",
         r"use self::*;",
@@ -628,17 +627,6 @@ fn merge_self_glob() {
     // FIXME: have it emit `use {self, *}`?
 }
 
-#[test]
-fn merge_glob() {
-    check_crate(
-        "syntax::SyntaxKind",
-        r"
-use syntax::{SyntaxKind::*};",
-        r"
-use syntax::{SyntaxKind::{*, self}};",
-    )
-}
-
 #[test]
 fn merge_glob_nested() {
     check_crate(
@@ -943,5 +931,5 @@ fn check_merge_only_fail(ra_fixture0: &str, ra_fixture1: &str, mb: MergeBehavior
 fn check_guess(ra_fixture: &str, expected: ImportGranularityGuess) {
     let syntax = ast::SourceFile::parse(ra_fixture).tree().syntax().clone();
     let file = super::ImportScope::from(syntax).unwrap();
-    assert_eq!(super::guess_granularity_from_scope(&file), expected);
+    assert_eq!(file.guess_granularity_from_scope(), expected);
 }
diff --git a/crates/syntax/src/tests.rs b/crates/syntax/src/tests.rs
index f8f7a3ad32..022db39f33 100644
--- a/crates/syntax/src/tests.rs
+++ b/crates/syntax/src/tests.rs
@@ -227,12 +227,9 @@ where
     T: crate::AstNode,
     F: Fn(&str) -> Result<T, ()>,
 {
-    dir_tests(&test_data_dir(), ok_paths, "rast", |text, path| {
-        if let Ok(node) = f(text) {
-            format!("{:#?}", crate::ast::AstNode::syntax(&node))
-        } else {
-            panic!("Failed to parse '{:?}'", path);
-        }
+    dir_tests(&test_data_dir(), ok_paths, "rast", |text, path| match f(text) {
+        Ok(node) => format!("{:#?}", crate::ast::AstNode::syntax(&node)),
+        Err(_) => panic!("Failed to parse '{:?}'", path),
     });
     dir_tests(&test_data_dir(), err_paths, "rast", |text, path| {
         if f(text).is_ok() {
diff --git a/crates/syntax/src/tests/sourcegen_ast.rs b/crates/syntax/src/tests/sourcegen_ast.rs
index c9f3c2cb8e..d2b5877490 100644
--- a/crates/syntax/src/tests/sourcegen_ast.rs
+++ b/crates/syntax/src/tests/sourcegen_ast.rs
@@ -215,7 +215,7 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> String {
         .flat_map(|node| node.traits.iter().map(move |t| (t, node)))
         .into_group_map()
         .into_iter()
-        .sorted_by_key(|(k, _)| k.clone())
+        .sorted_by_key(|(k, _)| *k)
         .map(|(trait_name, nodes)| {
             let name = format_ident!("Any{}", trait_name);
             let trait_name = format_ident!("{}", trait_name);
@@ -558,12 +558,13 @@ impl Field {
 }
 
 fn lower(grammar: &Grammar) -> AstSrc {
-    let mut res = AstSrc::default();
-
-    res.tokens = "Whitespace Comment String ByteString IntNumber FloatNumber"
-        .split_ascii_whitespace()
-        .map(|it| it.to_string())
-        .collect::<Vec<_>>();
+    let mut res = AstSrc {
+        tokens: "Whitespace Comment String ByteString IntNumber FloatNumber"
+            .split_ascii_whitespace()
+            .map(|it| it.to_string())
+            .collect::<Vec<_>>(),
+        ..Default::default()
+    };
 
     let nodes = grammar.iter().collect::<Vec<_>>();
 
diff --git a/crates/syntax/test_data/parser/inline/ok/0058_range_pat.rast b/crates/syntax/test_data/parser/inline/ok/0058_range_pat.rast
index 5d5803f751..1a8979db89 100644
--- a/crates/syntax/test_data/parser/inline/ok/0058_range_pat.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0058_range_pat.rast
@@ -1,5 +1,5 @@
-SOURCE_FILE@0..223
-  FN@0..222
+SOURCE_FILE@0..135
+  FN@0..134
     FN_KW@0..2 "fn"
     WHITESPACE@2..3 " "
     NAME@3..7
@@ -8,168 +8,92 @@ SOURCE_FILE@0..223
       L_PAREN@7..8 "("
       R_PAREN@8..9 ")"
     WHITESPACE@9..10 " "
-    BLOCK_EXPR@10..222
-      STMT_LIST@10..222
+    BLOCK_EXPR@10..134
+      STMT_LIST@10..134
         L_CURLY@10..11 "{"
         WHITESPACE@11..16 "\n    "
-        EXPR_STMT@16..132
-          MATCH_EXPR@16..132
-            MATCH_KW@16..21 "match"
-            WHITESPACE@21..22 " "
-            LITERAL@22..24
-              INT_NUMBER@22..24 "92"
-            WHITESPACE@24..25 " "
-            MATCH_ARM_LIST@25..132
-              L_CURLY@25..26 "{"
-              WHITESPACE@26..35 "\n        "
-              MATCH_ARM@35..51
-                RANGE_PAT@35..44
-                  LITERAL_PAT@35..36
-                    LITERAL@35..36
-                      INT_NUMBER@35..36 "0"
-                  WHITESPACE@36..37 " "
-                  DOT3@37..40 "..."
-                  WHITESPACE@40..41 " "
-                  LITERAL_PAT@41..44
-                    LITERAL@41..44
-                      INT_NUMBER@41..44 "100"
-                WHITESPACE@44..45 " "
-                FAT_ARROW@45..47 "=>"
-                WHITESPACE@47..48 " "
-                TUPLE_EXPR@48..50
-                  L_PAREN@48..49 "("
-                  R_PAREN@49..50 ")"
-                COMMA@50..51 ","
-              WHITESPACE@51..60 "\n        "
-              MATCH_ARM@60..78
-                RANGE_PAT@60..71
-                  LITERAL_PAT@60..63
-                    LITERAL@60..63
-                      INT_NUMBER@60..63 "101"
-                  WHITESPACE@63..64 " "
-                  DOT2EQ@64..67 "..="
-                  WHITESPACE@67..68 " "
-                  LITERAL_PAT@68..71
-                    LITERAL@68..71
-                      INT_NUMBER@68..71 "200"
-                WHITESPACE@71..72 " "
-                FAT_ARROW@72..74 "=>"
-                WHITESPACE@74..75 " "
-                TUPLE_EXPR@75..77
-                  L_PAREN@75..76 "("
-                  R_PAREN@76..77 ")"
-                COMMA@77..78 ","
-              WHITESPACE@78..87 "\n        "
-              MATCH_ARM@87..104
-                RANGE_PAT@87..97
-                  LITERAL_PAT@87..90
-                    LITERAL@87..90
-                      INT_NUMBER@87..90 "200"
-                  WHITESPACE@90..91 " "
-                  DOT2@91..93 ".."
-                  WHITESPACE@93..94 " "
-                  LITERAL_PAT@94..97
-                    LITERAL@94..97
-                      INT_NUMBER@94..97 "301"
-                WHITESPACE@97..98 " "
-                FAT_ARROW@98..100 "=>"
-                WHITESPACE@100..101 " "
-                TUPLE_EXPR@101..103
-                  L_PAREN@101..102 "("
-                  R_PAREN@102..103 ")"
-                COMMA@103..104 ","
-              WHITESPACE@104..113 "\n        "
-              MATCH_ARM@113..126
-                RANGE_PAT@113..119
-                  LITERAL_PAT@113..116
-                    LITERAL@113..116
-                      INT_NUMBER@113..116 "302"
-                  WHITESPACE@116..117 " "
-                  DOT2@117..119 ".."
-                WHITESPACE@119..120 " "
-                FAT_ARROW@120..122 "=>"
-                WHITESPACE@122..123 " "
-                TUPLE_EXPR@123..125
-                  L_PAREN@123..124 "("
-                  R_PAREN@124..125 ")"
-                COMMA@125..126 ","
-              WHITESPACE@126..131 "\n    "
-              R_CURLY@131..132 "}"
-        WHITESPACE@132..138 "\n\n    "
-        MATCH_EXPR@138..220
-          MATCH_KW@138..143 "match"
-          WHITESPACE@143..144 " "
-          CALL_EXPR@144..158
-            PATH_EXPR@144..148
-              PATH@144..148
-                PATH_SEGMENT@144..148
-                  NAME_REF@144..148
-                    IDENT@144..148 "Some"
-            ARG_LIST@148..158
-              L_PAREN@148..149 "("
-              CAST_EXPR@149..157
-                LITERAL@149..151
-                  INT_NUMBER@149..151 "10"
-                WHITESPACE@151..152 " "
-                AS_KW@152..154 "as"
-                WHITESPACE@154..155 " "
-                PATH_TYPE@155..157
-                  PATH@155..157
-                    PATH_SEGMENT@155..157
-                      NAME_REF@155..157
-                        IDENT@155..157 "u8"
-              R_PAREN@157..158 ")"
-          WHITESPACE@158..159 " "
-          MATCH_ARM_LIST@159..220
-            L_CURLY@159..160 "{"
-            WHITESPACE@160..169 "\n        "
-            MATCH_ARM@169..190
-              OR_PAT@169..183
-                TUPLE_STRUCT_PAT@169..176
-                  PATH@169..173
-                    PATH_SEGMENT@169..173
-                      NAME_REF@169..173
-                        IDENT@169..173 "Some"
-                  L_PAREN@173..174 "("
-                  LITERAL_PAT@174..175
-                    LITERAL@174..175
-                      INT_NUMBER@174..175 "0"
-                  R_PAREN@175..176 ")"
-                WHITESPACE@176..177 " "
-                PIPE@177..178 "|"
-                WHITESPACE@178..179 " "
-                IDENT_PAT@179..183
-                  NAME@179..183
-                    IDENT@179..183 "None"
-              WHITESPACE@183..184 " "
-              FAT_ARROW@184..186 "=>"
-              WHITESPACE@186..187 " "
-              TUPLE_EXPR@187..189
-                L_PAREN@187..188 "("
-                R_PAREN@188..189 ")"
-              COMMA@189..190 ","
-            WHITESPACE@190..199 "\n        "
-            MATCH_ARM@199..214
-              TUPLE_STRUCT_PAT@199..208
-                PATH@199..203
-                  PATH_SEGMENT@199..203
-                    NAME_REF@199..203
-                      IDENT@199..203 "Some"
-                L_PAREN@203..204 "("
-                RANGE_PAT@204..207
-                  LITERAL_PAT@204..205
-                    LITERAL@204..205
-                      INT_NUMBER@204..205 "1"
-                  DOT2@205..207 ".."
-                R_PAREN@207..208 ")"
-              WHITESPACE@208..209 " "
-              FAT_ARROW@209..211 "=>"
-              WHITESPACE@211..212 " "
-              TUPLE_EXPR@212..214
-                L_PAREN@212..213 "("
-                R_PAREN@213..214 ")"
-            WHITESPACE@214..219 "\n    "
-            R_CURLY@219..220 "}"
-        WHITESPACE@220..221 "\n"
-        R_CURLY@221..222 "}"
-  WHITESPACE@222..223 "\n"
+        MATCH_EXPR@16..132
+          MATCH_KW@16..21 "match"
+          WHITESPACE@21..22 " "
+          LITERAL@22..24
+            INT_NUMBER@22..24 "92"
+          WHITESPACE@24..25 " "
+          MATCH_ARM_LIST@25..132
+            L_CURLY@25..26 "{"
+            WHITESPACE@26..35 "\n        "
+            MATCH_ARM@35..51
+              RANGE_PAT@35..44
+                LITERAL_PAT@35..36
+                  LITERAL@35..36
+                    INT_NUMBER@35..36 "0"
+                WHITESPACE@36..37 " "
+                DOT3@37..40 "..."
+                WHITESPACE@40..41 " "
+                LITERAL_PAT@41..44
+                  LITERAL@41..44
+                    INT_NUMBER@41..44 "100"
+              WHITESPACE@44..45 " "
+              FAT_ARROW@45..47 "=>"
+              WHITESPACE@47..48 " "
+              TUPLE_EXPR@48..50
+                L_PAREN@48..49 "("
+                R_PAREN@49..50 ")"
+              COMMA@50..51 ","
+            WHITESPACE@51..60 "\n        "
+            MATCH_ARM@60..78
+              RANGE_PAT@60..71
+                LITERAL_PAT@60..63
+                  LITERAL@60..63
+                    INT_NUMBER@60..63 "101"
+                WHITESPACE@63..64 " "
+                DOT2EQ@64..67 "..="
+                WHITESPACE@67..68 " "
+                LITERAL_PAT@68..71
+                  LITERAL@68..71
+                    INT_NUMBER@68..71 "200"
+              WHITESPACE@71..72 " "
+              FAT_ARROW@72..74 "=>"
+              WHITESPACE@74..75 " "
+              TUPLE_EXPR@75..77
+                L_PAREN@75..76 "("
+                R_PAREN@76..77 ")"
+              COMMA@77..78 ","
+            WHITESPACE@78..87 "\n        "
+            MATCH_ARM@87..104
+              RANGE_PAT@87..97
+                LITERAL_PAT@87..90
+                  LITERAL@87..90
+                    INT_NUMBER@87..90 "200"
+                WHITESPACE@90..91 " "
+                DOT2@91..93 ".."
+                WHITESPACE@93..94 " "
+                LITERAL_PAT@94..97
+                  LITERAL@94..97
+                    INT_NUMBER@94..97 "301"
+              WHITESPACE@97..98 " "
+              FAT_ARROW@98..100 "=>"
+              WHITESPACE@100..101 " "
+              TUPLE_EXPR@101..103
+                L_PAREN@101..102 "("
+                R_PAREN@102..103 ")"
+              COMMA@103..104 ","
+            WHITESPACE@104..113 "\n        "
+            MATCH_ARM@113..126
+              RANGE_PAT@113..119
+                LITERAL_PAT@113..116
+                  LITERAL@113..116
+                    INT_NUMBER@113..116 "302"
+                WHITESPACE@116..117 " "
+                DOT2@117..119 ".."
+              WHITESPACE@119..120 " "
+              FAT_ARROW@120..122 "=>"
+              WHITESPACE@122..123 " "
+              TUPLE_EXPR@123..125
+                L_PAREN@123..124 "("
+                R_PAREN@124..125 ")"
+              COMMA@125..126 ","
+            WHITESPACE@126..131 "\n    "
+            R_CURLY@131..132 "}"
+        WHITESPACE@132..133 "\n"
+        R_CURLY@133..134 "}"
+  WHITESPACE@134..135 "\n"
diff --git a/crates/syntax/test_data/parser/inline/ok/0058_range_pat.rs b/crates/syntax/test_data/parser/inline/ok/0058_range_pat.rs
index fa91efd212..3833fbd8d5 100644
--- a/crates/syntax/test_data/parser/inline/ok/0058_range_pat.rs
+++ b/crates/syntax/test_data/parser/inline/ok/0058_range_pat.rs
@@ -5,9 +5,4 @@ fn main() {
         200 .. 301 => (),
         302 .. => (),
     }
-
-    match Some(10 as u8) {
-        Some(0) | None => (),
-        Some(1..) => ()
-    }
 }
diff --git a/crates/test_utils/src/assert_linear.rs b/crates/test_utils/src/assert_linear.rs
index 6ecc232e1e..24502ddb41 100644
--- a/crates/test_utils/src/assert_linear.rs
+++ b/crates/test_utils/src/assert_linear.rs
@@ -43,7 +43,7 @@ impl AssertLinear {
     }
 
     pub fn sample(&mut self, x: f64, y: f64) {
-        self.rounds.last_mut().unwrap().samples.push((x, y))
+        self.rounds.last_mut().unwrap().samples.push((x, y));
     }
 }
 
@@ -54,7 +54,7 @@ impl Drop for AssertLinear {
             for round in &self.rounds {
                 eprintln!("\n{}", round.plot);
             }
-            panic!("Doesn't look linear!")
+            panic!("Doesn't look linear!");
         }
     }
 }
diff --git a/crates/test_utils/src/fixture.rs b/crates/test_utils/src/fixture.rs
index f2013b34c5..5ea7a994b4 100644
--- a/crates/test_utils/src/fixture.rs
+++ b/crates/test_utils/src/fixture.rs
@@ -142,14 +142,14 @@ impl Fixture {
 
             if line.starts_with("//-") {
                 let meta = Fixture::parse_meta_line(line);
-                res.push(meta)
+                res.push(meta);
             } else {
                 if line.starts_with("// ")
                     && line.contains(':')
                     && !line.contains("::")
                     && line.chars().all(|it| !it.is_uppercase())
                 {
-                    panic!("looks like invalid metadata line: {:?}", line)
+                    panic!("looks like invalid metadata line: {:?}", line);
                 }
 
                 if let Some(entry) = res.last_mut() {
@@ -256,9 +256,9 @@ impl MiniCore {
         let line = line.strip_prefix("//- minicore:").unwrap().trim();
         for entry in line.split(", ") {
             if res.has_flag(entry) {
-                panic!("duplicate minicore flag: {:?}", entry)
+                panic!("duplicate minicore flag: {:?}", entry);
             }
-            res.activated_flags.push(entry.to_string())
+            res.activated_flags.push(entry.to_string());
         }
 
         res
@@ -310,7 +310,7 @@ impl MiniCore {
         // Fixed point loop to compute transitive closure of flags.
         loop {
             let mut changed = false;
-            for &(u, v) in implications.iter() {
+            for &(u, v) in &implications {
                 if self.has_flag(u) && !self.has_flag(v) {
                     self.activated_flags.push(v.to_string());
                     changed = true;
@@ -354,7 +354,7 @@ impl MiniCore {
             }
 
             if keep {
-                buf.push_str(line)
+                buf.push_str(line);
             }
             if line_region {
                 active_regions.pop().unwrap();
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs
index 7b43fb9de5..146e4f0c30 100644
--- a/crates/test_utils/src/lib.rs
+++ b/crates/test_utils/src/lib.rs
@@ -244,7 +244,7 @@ pub fn extract_annotations(text: &str) -> Vec<(TextRange, String)> {
 
                             range + line_start.1
                         };
-                        res.push((range, content))
+                        res.push((range, content));
                     }
                     LineAnnotation::Continuation { mut offset, content } => {
                         offset += annotation_offset;
@@ -301,7 +301,7 @@ fn extract_line_annotations(mut line: &str) -> Vec<LineAnnotation> {
         let mut file = false;
         if !continuation && content.starts_with("file") {
             file = true;
-            content = &content["file".len()..]
+            content = &content["file".len()..];
         }
 
         let content = content.trim().to_string();
@@ -371,7 +371,7 @@ fn main() {
 pub fn skip_slow_tests() -> bool {
     let should_skip = std::env::var("CI").is_err() && std::env::var("RUN_SLOW_TESTS").is_err();
     if should_skip {
-        eprintln!("ignoring slow test")
+        eprintln!("ignoring slow test");
     } else {
         let path = project_root().join("./target/.slow_tests_cookie");
         fs::write(&path, ".").unwrap();
@@ -432,7 +432,7 @@ pub fn bench(label: &'static str) -> impl Drop {
 
     impl Drop for Bencher {
         fn drop(&mut self) {
-            eprintln!("{}: {}", self.label, self.sw.elapsed())
+            eprintln!("{}: {}", self.label, self.sw.elapsed());
         }
     }
 
diff --git a/crates/test_utils/src/minicore.rs b/crates/test_utils/src/minicore.rs
index 045b4898e5..5e17047a40 100644
--- a/crates/test_utils/src/minicore.rs
+++ b/crates/test_utils/src/minicore.rs
@@ -300,17 +300,6 @@ pub mod ops {
             #[lang = "branch"]
             fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
         }
-
-        impl<B, C> Try for ControlFlow<B, C> {
-            type Output = C;
-            type Residual = ControlFlow<B, convert::Infallible>;
-            fn from_output(output: Self::Output) -> Self {}
-            fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {}
-        }
-
-        impl<B, C> FromResidual for ControlFlow<B, C> {
-            fn from_residual(residual: ControlFlow<B, convert::Infallible>) -> Self {}
-        }
     }
     pub use self::try_::{ControlFlow, FromResidual, Try};
     // endregion:try