about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2023-03-28 16:22:12 +0200
committerLukas Wirth <lukastw97@gmail.com>2023-03-28 16:32:26 +0200
commit8ea1afce2803458eeb2b39a970472e3acdba82c6 (patch)
tree34e0cfd4a5252112f9195d7d4e1b0ffe4a82c6fb
parent284c1741d6536be6e7d4d4d252c424b90d6f1e45 (diff)
downloadrust-8ea1afce2803458eeb2b39a970472e3acdba82c6.tar.gz
rust-8ea1afce2803458eeb2b39a970472e3acdba82c6.zip
Simplify
-rw-r--r--crates/hir-ty/src/infer/coerce.rs2
-rw-r--r--crates/hir-ty/src/infer/expr.rs10
-rw-r--r--crates/hir-ty/src/interner.rs140
-rw-r--r--crates/hir-ty/src/lib.rs2
-rw-r--r--crates/hir-ty/src/mir/eval.rs6
-rw-r--r--crates/hir-ty/src/utils.rs4
-rw-r--r--crates/ide-assists/src/handlers/add_missing_match_arms.rs2
-rw-r--r--crates/ide-assists/src/handlers/convert_let_else_to_match.rs161
-rw-r--r--crates/ide-assists/src/handlers/convert_match_to_let_else.rs37
-rw-r--r--crates/ide-assists/src/handlers/generate_constant.rs6
-rw-r--r--crates/ide-assists/src/handlers/reorder_fields.rs5
-rw-r--r--crates/ide-assists/src/handlers/unwrap_block.rs8
-rw-r--r--crates/ide-assists/src/tests/generated.rs2
-rw-r--r--crates/ide-diagnostics/src/handlers/unlinked_file.rs2
-rw-r--r--crates/rust-analyzer/src/cli/scip.rs3
-rw-r--r--crates/rust-analyzer/src/to_proto.rs2
16 files changed, 196 insertions, 196 deletions
diff --git a/crates/hir-ty/src/infer/coerce.rs b/crates/hir-ty/src/infer/coerce.rs
index 6e899249b69..c75627e0f7a 100644
--- a/crates/hir-ty/src/infer/coerce.rs
+++ b/crates/hir-ty/src/infer/coerce.rs
@@ -151,7 +151,7 @@ impl CoerceMany {
             if let Some(id) = expr {
                 ctx.result.type_mismatches.insert(
                     id.into(),
-                    TypeMismatch { expected: self.merged_ty().clone(), actual: expr_ty.clone() },
+                    TypeMismatch { expected: self.merged_ty(), actual: expr_ty.clone() },
                 );
             }
             cov_mark::hit!(coerce_merge_fail_fallback);
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index d52188bb284..b524837abbb 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -331,7 +331,7 @@ impl<'a> InferenceContext<'a> {
                 let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
                 let prev_ret_ty = mem::replace(&mut self.return_ty, ret_ty.clone());
                 let prev_ret_coercion =
-                    mem::replace(&mut self.return_coercion, Some(CoerceMany::new(ret_ty.clone())));
+                    mem::replace(&mut self.return_coercion, Some(CoerceMany::new(ret_ty)));
                 let prev_resume_yield_tys =
                     mem::replace(&mut self.resume_yield_tys, resume_yield_tys);
 
@@ -402,7 +402,7 @@ impl<'a> InferenceContext<'a> {
                                     .push(callee_ty.clone())
                                     .push(TyBuilder::tuple_with(params.iter().cloned()))
                                     .build();
-                                self.write_method_resolution(tgt_expr, func, subst.clone());
+                                self.write_method_resolution(tgt_expr, func, subst)
                             }
                         }
                         self.write_expr_adj(*callee, adjustments);
@@ -803,7 +803,7 @@ impl<'a> InferenceContext<'a> {
                             .push(self_ty.clone())
                             .push(index_ty.clone())
                             .build();
-                        self.write_method_resolution(tgt_expr, func, substs.clone());
+                        self.write_method_resolution(tgt_expr, func, substs);
                     }
                     self.resolve_associated_type_with_params(
                         self_ty,
@@ -912,7 +912,7 @@ impl<'a> InferenceContext<'a> {
                 (elem_ty, consteval::usize_const(self.db, Some(0), krate))
             }
             Array::ElementList { elements, .. } => {
-                let mut coerce = CoerceMany::new(elem_ty.clone());
+                let mut coerce = CoerceMany::new(elem_ty);
                 for &expr in elements.iter() {
                     let cur_elem_ty = self.infer_expr_inner(expr, &expected);
                     coerce.coerce(self, Some(expr), &cur_elem_ty);
@@ -1214,7 +1214,7 @@ impl<'a> InferenceContext<'a> {
         let g = self.resolver.update_to_inner_scope(self.db.upcast(), self.owner, expr);
 
         let (break_ty, ty) =
-            self.with_breakable_ctx(BreakableKind::Block, Some(coerce_ty.clone()), label, |this| {
+            self.with_breakable_ctx(BreakableKind::Block, Some(coerce_ty), label, |this| {
                 for stmt in statements {
                     match stmt {
                         Statement::Let { pat, type_ref, initializer, else_branch } => {
diff --git a/crates/hir-ty/src/interner.rs b/crates/hir-ty/src/interner.rs
index aea7e9762fd..874f808cda1 100644
--- a/crates/hir-ty/src/interner.rs
+++ b/crates/hir-ty/src/interner.rs
@@ -51,8 +51,8 @@ impl chalk_ir::interner::Interner for Interner {
     type InternedGoal = Arc<GoalData<Self>>;
     type InternedGoals = Vec<Goal<Self>>;
     type InternedSubstitution = Interned<InternedWrapper<SmallVec<[GenericArg; 2]>>>;
-    type InternedProgramClause = chalk_ir::ProgramClauseData<Self>;
     type InternedProgramClauses = Interned<InternedWrapper<Vec<chalk_ir::ProgramClause<Self>>>>;
+    type InternedProgramClause = chalk_ir::ProgramClauseData<Self>;
     type InternedQuantifiedWhereClauses =
         Interned<InternedWrapper<Vec<chalk_ir::QuantifiedWhereClause<Self>>>>;
     type InternedVariableKinds = Interned<InternedWrapper<Vec<chalk_ir::VariableKind<Interner>>>>;
@@ -86,6 +86,27 @@ impl chalk_ir::interner::Interner for Interner {
         tls::with_current_program(|prog| Some(prog?.debug_assoc_type_id(id, fmt)))
     }
 
+    fn debug_opaque_ty_id(
+        opaque_ty_id: chalk_ir::OpaqueTyId<Self>,
+        fmt: &mut fmt::Formatter<'_>,
+    ) -> Option<fmt::Result> {
+        Some(write!(fmt, "OpaqueTy#{}", opaque_ty_id.0))
+    }
+
+    fn debug_fn_def_id(
+        fn_def_id: chalk_ir::FnDefId<Self>,
+        fmt: &mut fmt::Formatter<'_>,
+    ) -> Option<fmt::Result> {
+        tls::with_current_program(|prog| Some(prog?.debug_fn_def_id(fn_def_id, fmt)))
+    }
+
+    fn debug_closure_id(
+        _fn_def_id: chalk_ir::ClosureId<Self>,
+        _fmt: &mut fmt::Formatter<'_>,
+    ) -> Option<fmt::Result> {
+        None
+    }
+
     fn debug_alias(
         alias: &chalk_ir::AliasTy<Interner>,
         fmt: &mut fmt::Formatter<'_>,
@@ -113,13 +134,6 @@ impl chalk_ir::interner::Interner for Interner {
         Some(write!(fmt, "{:?}", opaque_ty.opaque_ty_id))
     }
 
-    fn debug_opaque_ty_id(
-        opaque_ty_id: chalk_ir::OpaqueTyId<Self>,
-        fmt: &mut fmt::Formatter<'_>,
-    ) -> Option<fmt::Result> {
-        Some(write!(fmt, "OpaqueTy#{}", opaque_ty_id.0))
-    }
-
     fn debug_ty(ty: &chalk_ir::Ty<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
         Some(write!(fmt, "{:?}", ty.data(Interner)))
     }
@@ -131,76 +145,56 @@ impl chalk_ir::interner::Interner for Interner {
         Some(write!(fmt, "{:?}", lifetime.data(Interner)))
     }
 
-    fn debug_generic_arg(
-        parameter: &GenericArg,
-        fmt: &mut fmt::Formatter<'_>,
-    ) -> Option<fmt::Result> {
-        Some(write!(fmt, "{:?}", parameter.data(Interner).inner_debug()))
-    }
-
-    fn debug_goal(goal: &Goal<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
-        let goal_data = goal.data(Interner);
-        Some(write!(fmt, "{goal_data:?}"))
-    }
-
-    fn debug_goals(
-        goals: &chalk_ir::Goals<Interner>,
-        fmt: &mut fmt::Formatter<'_>,
-    ) -> Option<fmt::Result> {
-        Some(write!(fmt, "{:?}", goals.debug(Interner)))
-    }
-
-    fn debug_program_clause_implication(
-        pci: &chalk_ir::ProgramClauseImplication<Interner>,
-        fmt: &mut fmt::Formatter<'_>,
-    ) -> Option<fmt::Result> {
-        Some(write!(fmt, "{:?}", pci.debug(Interner)))
-    }
-
-    fn debug_substitution(
-        substitution: &chalk_ir::Substitution<Interner>,
+    fn debug_const(
+        constant: &chalk_ir::Const<Self>,
         fmt: &mut fmt::Formatter<'_>,
     ) -> Option<fmt::Result> {
-        Some(write!(fmt, "{:?}", substitution.debug(Interner)))
+        Some(write!(fmt, "{:?}", constant.data(Interner)))
     }
 
-    fn debug_separator_trait_ref(
-        separator_trait_ref: &chalk_ir::SeparatorTraitRef<'_, Interner>,
+    fn debug_generic_arg(
+        parameter: &GenericArg,
         fmt: &mut fmt::Formatter<'_>,
     ) -> Option<fmt::Result> {
-        Some(write!(fmt, "{:?}", separator_trait_ref.debug(Interner)))
+        Some(write!(fmt, "{:?}", parameter.data(Interner).inner_debug()))
     }
 
-    fn debug_fn_def_id(
-        fn_def_id: chalk_ir::FnDefId<Self>,
-        fmt: &mut fmt::Formatter<'_>,
-    ) -> Option<fmt::Result> {
-        tls::with_current_program(|prog| Some(prog?.debug_fn_def_id(fn_def_id, fmt)))
-    }
-    fn debug_const(
-        constant: &chalk_ir::Const<Self>,
-        fmt: &mut fmt::Formatter<'_>,
-    ) -> Option<fmt::Result> {
-        Some(write!(fmt, "{:?}", constant.data(Interner)))
-    }
     fn debug_variable_kinds(
         variable_kinds: &chalk_ir::VariableKinds<Self>,
         fmt: &mut fmt::Formatter<'_>,
     ) -> Option<fmt::Result> {
         Some(write!(fmt, "{:?}", variable_kinds.as_slice(Interner)))
     }
+
     fn debug_variable_kinds_with_angles(
         variable_kinds: &chalk_ir::VariableKinds<Self>,
         fmt: &mut fmt::Formatter<'_>,
     ) -> Option<fmt::Result> {
         Some(write!(fmt, "{:?}", variable_kinds.inner_debug(Interner)))
     }
+
     fn debug_canonical_var_kinds(
         canonical_var_kinds: &chalk_ir::CanonicalVarKinds<Self>,
         fmt: &mut fmt::Formatter<'_>,
     ) -> Option<fmt::Result> {
         Some(write!(fmt, "{:?}", canonical_var_kinds.as_slice(Interner)))
     }
+    fn debug_goal(goal: &Goal<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
+        let goal_data = goal.data(Interner);
+        Some(write!(fmt, "{goal_data:?}"))
+    }
+    fn debug_goals(
+        goals: &chalk_ir::Goals<Interner>,
+        fmt: &mut fmt::Formatter<'_>,
+    ) -> Option<fmt::Result> {
+        Some(write!(fmt, "{:?}", goals.debug(Interner)))
+    }
+    fn debug_program_clause_implication(
+        pci: &chalk_ir::ProgramClauseImplication<Interner>,
+        fmt: &mut fmt::Formatter<'_>,
+    ) -> Option<fmt::Result> {
+        Some(write!(fmt, "{:?}", pci.debug(Interner)))
+    }
     fn debug_program_clause(
         clause: &chalk_ir::ProgramClause<Self>,
         fmt: &mut fmt::Formatter<'_>,
@@ -213,6 +207,19 @@ impl chalk_ir::interner::Interner for Interner {
     ) -> Option<fmt::Result> {
         Some(write!(fmt, "{:?}", clauses.as_slice(Interner)))
     }
+    fn debug_substitution(
+        substitution: &chalk_ir::Substitution<Interner>,
+        fmt: &mut fmt::Formatter<'_>,
+    ) -> Option<fmt::Result> {
+        Some(write!(fmt, "{:?}", substitution.debug(Interner)))
+    }
+    fn debug_separator_trait_ref(
+        separator_trait_ref: &chalk_ir::SeparatorTraitRef<'_, Interner>,
+        fmt: &mut fmt::Formatter<'_>,
+    ) -> Option<fmt::Result> {
+        Some(write!(fmt, "{:?}", separator_trait_ref.debug(Interner)))
+    }
+
     fn debug_quantified_where_clauses(
         clauses: &chalk_ir::QuantifiedWhereClauses<Self>,
         fmt: &mut fmt::Formatter<'_>,
@@ -220,6 +227,13 @@ impl chalk_ir::interner::Interner for Interner {
         Some(write!(fmt, "{:?}", clauses.as_slice(Interner)))
     }
 
+    fn debug_constraints(
+        _clauses: &chalk_ir::Constraints<Self>,
+        _fmt: &mut fmt::Formatter<'_>,
+    ) -> Option<fmt::Result> {
+        None
+    }
+
     fn intern_ty(self, kind: chalk_ir::TyKind<Self>) -> Self::InternedType {
         let flags = kind.compute_flags(self);
         Interned::new(InternedWrapper(chalk_ir::TyData { kind, flags }))
@@ -272,6 +286,10 @@ impl chalk_ir::interner::Interner for Interner {
         Arc::new(goal)
     }
 
+    fn goal_data(self, goal: &Self::InternedGoal) -> &GoalData<Self> {
+        goal
+    }
+
     fn intern_goals<E>(
         self,
         data: impl IntoIterator<Item = Result<Goal<Self>, E>>,
@@ -279,10 +297,6 @@ impl chalk_ir::interner::Interner for Interner {
         data.into_iter().collect()
     }
 
-    fn goal_data(self, goal: &Self::InternedGoal) -> &GoalData<Self> {
-        goal
-    }
-
     fn goals_data(self, goals: &Self::InternedGoals) -> &[Goal<Interner>] {
         goals
     }
@@ -367,32 +381,18 @@ impl chalk_ir::interner::Interner for Interner {
     ) -> &[chalk_ir::CanonicalVarKind<Self>] {
         canonical_var_kinds
     }
-
     fn intern_constraints<E>(
         self,
         data: impl IntoIterator<Item = Result<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>, E>>,
     ) -> Result<Self::InternedConstraints, E> {
         data.into_iter().collect()
     }
-
     fn constraints_data(
         self,
         constraints: &Self::InternedConstraints,
     ) -> &[chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>] {
         constraints
     }
-    fn debug_closure_id(
-        _fn_def_id: chalk_ir::ClosureId<Self>,
-        _fmt: &mut fmt::Formatter<'_>,
-    ) -> Option<fmt::Result> {
-        None
-    }
-    fn debug_constraints(
-        _clauses: &chalk_ir::Constraints<Self>,
-        _fmt: &mut fmt::Formatter<'_>,
-    ) -> Option<fmt::Result> {
-        None
-    }
 
     fn intern_variances<E>(
         self,
diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs
index 782a8ab4aa2..ea494a0dbde 100644
--- a/crates/hir-ty/src/lib.rs
+++ b/crates/hir-ty/src/lib.rs
@@ -588,7 +588,7 @@ pub fn callable_sig_from_fnonce(
     let fn_once_trait = FnTrait::FnOnce.get_id(db, krate)?;
     let output_assoc_type = db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?;
 
-    let mut table = InferenceTable::new(db, env.clone());
+    let mut table = InferenceTable::new(db, env);
     let b = TyBuilder::trait_ref(db, fn_once_trait);
     if b.remaining() != 2 {
         return None;
diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs
index 7b83645faef..84b59b5eeb9 100644
--- a/crates/hir-ty/src/mir/eval.rs
+++ b/crates/hir-ty/src/mir/eval.rs
@@ -1414,7 +1414,7 @@ impl Evaluator<'_> {
             }
             CallableDefId::StructId(id) => {
                 let (size, variant_layout, tag) =
-                    self.layout_of_variant(id.into(), generic_args.clone(), &locals)?;
+                    self.layout_of_variant(id.into(), generic_args, &locals)?;
                 let result = self.make_by_layout(
                     size,
                     &variant_layout,
@@ -1425,7 +1425,7 @@ impl Evaluator<'_> {
             }
             CallableDefId::EnumVariantId(id) => {
                 let (size, variant_layout, tag) =
-                    self.layout_of_variant(id.into(), generic_args.clone(), &locals)?;
+                    self.layout_of_variant(id.into(), generic_args, &locals)?;
                 let result = self.make_by_layout(
                     size,
                     &variant_layout,
@@ -1507,7 +1507,7 @@ impl Evaluator<'_> {
                 );
             }
             let (imp, generic_args) =
-                lookup_impl_method(self.db, self.trait_env.clone(), def, generic_args.clone());
+                lookup_impl_method(self.db, self.trait_env.clone(), def, generic_args);
             let generic_args = self.subst_filler(&generic_args, &locals);
             let def = imp.into();
             let mir_body =
diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs
index a6967414aa8..9d97ab84a56 100644
--- a/crates/hir-ty/src/utils.rs
+++ b/crates/hir-ty/src/utils.rs
@@ -69,9 +69,7 @@ pub(super) fn all_super_trait_refs<T>(
     cb: impl FnMut(TraitRef) -> Option<T>,
 ) -> Option<T> {
     let seen = iter::once(trait_ref.trait_id).collect();
-    let mut stack = Vec::new();
-    stack.push(trait_ref);
-    SuperTraits { db, seen, stack }.find_map(cb)
+    SuperTraits { db, seen, stack: vec![trait_ref] }.find_map(cb)
 }
 
 struct SuperTraits<'a> {
diff --git a/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/crates/ide-assists/src/handlers/add_missing_match_arms.rs
index 5d81e8cfeac..7384390f28b 100644
--- a/crates/ide-assists/src/handlers/add_missing_match_arms.rs
+++ b/crates/ide-assists/src/handlers/add_missing_match_arms.rs
@@ -148,7 +148,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
             return None;
         }
 
-        let variants_of_enums = vec![variants.clone(); len];
+        let variants_of_enums = vec![variants; len];
 
         let missing_pats = variants_of_enums
             .into_iter()
diff --git a/crates/ide-assists/src/handlers/convert_let_else_to_match.rs b/crates/ide-assists/src/handlers/convert_let_else_to_match.rs
index c82a3b53032..5f7056b9c1c 100644
--- a/crates/ide-assists/src/handlers/convert_let_else_to_match.rs
+++ b/crates/ide-assists/src/handlers/convert_let_else_to_match.rs
@@ -5,6 +5,88 @@ use syntax::T;
 
 use crate::{AssistContext, AssistId, AssistKind, Assists};
 
+// Assist: convert_let_else_to_match
+//
+// Converts let-else statement to let statement and match expression.
+//
+// ```
+// fn main() {
+//     let Ok(mut x) = f() else$0 { return };
+// }
+// ```
+// ->
+// ```
+// fn main() {
+//     let mut x = match f() {
+//         Ok(x) => x,
+//         _ => return,
+//     };
+// }
+// ```
+pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
+    // should focus on else token to trigger
+    let let_stmt = ctx
+        .find_token_syntax_at_offset(T![else])
+        .and_then(|it| it.parent()?.parent())
+        .or_else(|| ctx.find_token_syntax_at_offset(T![let])?.parent())?;
+    let let_stmt = LetStmt::cast(let_stmt)?;
+    let let_else_block = let_stmt.let_else()?.block_expr()?;
+    let let_init = let_stmt.initializer()?;
+    if let_stmt.ty().is_some() {
+        // don't support let with type annotation
+        return None;
+    }
+    let pat = let_stmt.pat()?;
+    let mut binders = Vec::new();
+    binders_in_pat(&mut binders, &pat, &ctx.sema)?;
+
+    let target = let_stmt.syntax().text_range();
+    acc.add(
+        AssistId("convert_let_else_to_match", AssistKind::RefactorRewrite),
+        "Convert let-else to let and match",
+        target,
+        |edit| {
+            let indent_level = let_stmt.indent_level().0 as usize;
+            let indent = "    ".repeat(indent_level);
+            let indent1 = "    ".repeat(indent_level + 1);
+
+            let binders_str = binders_to_str(&binders, false);
+            let binders_str_mut = binders_to_str(&binders, true);
+
+            let init_expr = let_init.syntax().text();
+            let mut pat_no_mut = pat.syntax().text().to_string();
+            // remove the mut from the pattern
+            for (b, ismut) in binders.iter() {
+                if *ismut {
+                    pat_no_mut = pat_no_mut.replace(&format!("mut {b}"), &b.to_string());
+                }
+            }
+
+            let only_expr = let_else_block.statements().next().is_none();
+            let branch2 = match &let_else_block.tail_expr() {
+                Some(tail) if only_expr => format!("{tail},"),
+                _ => let_else_block.syntax().text().to_string(),
+            };
+            let replace = if binders.is_empty() {
+                format!(
+                    "match {init_expr} {{
+{indent1}{pat_no_mut} => {binders_str}
+{indent1}_ => {branch2}
+{indent}}}"
+                )
+            } else {
+                format!(
+                    "let {binders_str_mut} = match {init_expr} {{
+{indent1}{pat_no_mut} => {binders_str},
+{indent1}_ => {branch2}
+{indent}}};"
+                )
+            };
+            edit.replace(target, replace);
+        },
+    )
+}
+
 /// Gets a list of binders in a pattern, and whether they are mut.
 fn binders_in_pat(
     acc: &mut Vec<(Name, bool)>,
@@ -97,85 +179,6 @@ fn binders_to_str(binders: &[(Name, bool)], addmut: bool) -> String {
     }
 }
 
-// Assist: convert_let_else_to_match
-//
-// Converts let-else statement to let statement and match expression.
-//
-// ```
-// fn main() {
-//     let Ok(mut x) = f() else$0 { return };
-// }
-// ```
-// ->
-// ```
-// fn main() {
-//     let mut x = match f() {
-//         Ok(x) => x,
-//         _ => return,
-//     };
-// }
-// ```
-pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
-    // should focus on else token to trigger
-    let else_token = ctx.find_token_syntax_at_offset(T![else])?;
-    let let_stmt = LetStmt::cast(else_token.parent()?.parent()?)?;
-    let let_else_block = let_stmt.let_else()?.block_expr()?;
-    let let_init = let_stmt.initializer()?;
-    if let_stmt.ty().is_some() {
-        // don't support let with type annotation
-        return None;
-    }
-    let pat = let_stmt.pat()?;
-    let mut binders = Vec::new();
-    binders_in_pat(&mut binders, &pat, &ctx.sema)?;
-
-    let target = let_stmt.syntax().text_range();
-    acc.add(
-        AssistId("convert_let_else_to_match", AssistKind::RefactorRewrite),
-        "Convert let-else to let and match",
-        target,
-        |edit| {
-            let indent_level = let_stmt.indent_level().0 as usize;
-            let indent = "    ".repeat(indent_level);
-            let indent1 = "    ".repeat(indent_level + 1);
-
-            let binders_str = binders_to_str(&binders, false);
-            let binders_str_mut = binders_to_str(&binders, true);
-
-            let init_expr = let_init.syntax().text();
-            let mut pat_no_mut = pat.syntax().text().to_string();
-            // remove the mut from the pattern
-            for (b, ismut) in binders.iter() {
-                if *ismut {
-                    pat_no_mut = pat_no_mut.replace(&format!("mut {b}"), &b.to_string());
-                }
-            }
-
-            let only_expr = let_else_block.statements().next().is_none();
-            let branch2 = match &let_else_block.tail_expr() {
-                Some(tail) if only_expr => format!("{tail},"),
-                _ => let_else_block.syntax().text().to_string(),
-            };
-            let replace = if binders.is_empty() {
-                format!(
-                    "match {init_expr} {{
-{indent1}{pat_no_mut} => {binders_str}
-{indent1}_ => {branch2}
-{indent}}}"
-                )
-            } else {
-                format!(
-                    "let {binders_str_mut} = match {init_expr} {{
-{indent1}{pat_no_mut} => {binders_str},
-{indent1}_ => {branch2}
-{indent}}};"
-                )
-            };
-            edit.replace(target, replace);
-        },
-    )
-}
-
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/crates/ide-assists/src/handlers/convert_match_to_let_else.rs b/crates/ide-assists/src/handlers/convert_match_to_let_else.rs
index 7f2c01772ba..fc6236a1755 100644
--- a/crates/ide-assists/src/handlers/convert_match_to_let_else.rs
+++ b/crates/ide-assists/src/handlers/convert_match_to_let_else.rs
@@ -16,7 +16,7 @@ use crate::{
 // ```
 // # //- minicore: option
 // fn foo(opt: Option<()>) {
-//     let val = $0match opt {
+//     let val$0 = match opt {
 //         Some(it) => it,
 //         None => return,
 //     };
@@ -30,7 +30,10 @@ use crate::{
 // ```
 pub(crate) fn convert_match_to_let_else(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
     let let_stmt: ast::LetStmt = ctx.find_node_at_offset()?;
-    let binding = let_stmt.pat()?;
+    let pat = let_stmt.pat()?;
+    if ctx.offset() > pat.syntax().text_range().end() {
+        return None;
+    }
 
     let Some(ast::Expr::MatchExpr(initializer)) = let_stmt.initializer() else { return None };
     let initializer_expr = initializer.expr()?;
@@ -56,7 +59,7 @@ pub(crate) fn convert_match_to_let_else(acc: &mut Assists, ctx: &AssistContext<'
         let_stmt.syntax().text_range(),
         |builder| {
             let extracting_arm_pat =
-                rename_variable(&extracting_arm_pat, &extracted_variable_positions, binding);
+                rename_variable(&extracting_arm_pat, &extracted_variable_positions, pat);
             builder.replace(
                 let_stmt.syntax().text_range(),
                 format!("let {extracting_arm_pat} = {initializer_expr} else {diverging_arm_expr};"),
@@ -161,7 +164,7 @@ mod tests {
             r#"
 //- minicore: option
 fn foo(opt: Option<()>) {
-    let val = $0match opt {
+    let val$0 = match opt {
         Some(it) => it,
         None => (),
     };
@@ -211,7 +214,7 @@ fn foo(opt: Option<Foo>) -> Result<u32, ()> {
             r#"
 //- minicore: option
 fn foo(opt: Option<i32>) {
-    let val = $0match opt {
+    let val$0 = match opt {
         Some(it) => it + 1,
         None => return,
     };
@@ -224,7 +227,7 @@ fn foo(opt: Option<i32>) {
             r#"
 //- minicore: option
 fn foo(opt: Option<()>) {
-    let val = $0match opt {
+    let val$0 = match opt {
         Some(it) => {
             let _ = 1 + 1;
             it
@@ -244,7 +247,7 @@ fn foo(opt: Option<()>) {
             r#"
 //- minicore: option
 fn foo(opt: Option<()>) {
-    let val = $0match opt {
+    let val$0 = match opt {
         Some(it) if 2 > 1 => it,
         None => return,
     };
@@ -260,7 +263,7 @@ fn foo(opt: Option<()>) {
             r#"
 //- minicore: option
 fn foo(opt: Option<()>) {
-    let val = $0match opt {
+    let val$0 = match opt {
         Some(it) => it,
         None => return,
     };
@@ -281,7 +284,7 @@ fn foo(opt: Option<()>) {
             r#"
 //- minicore: option
 fn foo(opt: Option<()>) {
-    let ref mut val = $0match opt {
+    let ref mut val$0 = match opt {
         Some(it) => it,
         None => return,
     };
@@ -302,7 +305,7 @@ fn foo(opt: Option<()>) {
             r#"
 //- minicore: option, result
 fn foo(opt: Option<Result<()>>) {
-    let val = $0match opt {
+    let val$0 = match opt {
         Some(Ok(it)) => it,
         _ => return,
     };
@@ -324,7 +327,7 @@ fn foo(opt: Option<Result<()>>) {
 //- minicore: option
 fn foo(opt: Option<()>) {
     loop {
-        let val = $0match opt {
+        let val$0 = match opt {
             Some(it) => it,
             None => break,
         };
@@ -346,7 +349,7 @@ fn foo(opt: Option<()>) {
 //- minicore: option
 fn foo(opt: Option<()>) {
     loop {
-        let val = $0match opt {
+        let val$0 = match opt {
             Some(it) => it,
             None => continue,
         };
@@ -370,7 +373,7 @@ fn panic() -> ! {}
 
 fn foo(opt: Option<()>) {
     loop {
-        let val = $0match opt {
+        let val$0 = match opt {
             Some(it) => it,
             None => panic(),
         };
@@ -401,7 +404,7 @@ struct Point {
 }
 
 fn foo(opt: Option<Point>) {
-    let val = $0match opt {
+    let val$0 = match opt {
         Some(Point { x: 0, y }) => y,
         _ => return,
     };
@@ -427,7 +430,7 @@ fn foo(opt: Option<Point>) {
             r#"
 //- minicore: option
 fn foo(opt: Option<i32>) -> Option<i32> {
-    let val = $0match opt {
+    let val$0 = match opt {
         it @ Some(42) => it,
         _ => return None,
     };
@@ -450,7 +453,7 @@ fn foo(opt: Option<i32>) -> Option<i32> {
             r#"
 //- minicore: option
 fn f() {
-    let (x, y) = $0match Some((0, 1)) {
+    let (x, y)$0 = match Some((0, 1)) {
         Some(it) => it,
         None => return,
     };
@@ -471,7 +474,7 @@ fn f() {
             r#"
 //- minicore: option
 fn f() {
-    let x = $0match Some(()) {
+    let x$0 = match Some(()) {
         Some(it) => it,
         None => {//comment
             println!("nope");
diff --git a/crates/ide-assists/src/handlers/generate_constant.rs b/crates/ide-assists/src/handlers/generate_constant.rs
index ccdfcb0d9e4..57bb679729f 100644
--- a/crates/ide-assists/src/handlers/generate_constant.rs
+++ b/crates/ide-assists/src/handlers/generate_constant.rs
@@ -106,10 +106,10 @@ fn get_text_for_generate_constant(
     let mut text = format!("{vis}const {constant_token}: {type_name} = $0;");
     while let Some(name_ref) = not_exist_name_ref.pop() {
         let vis = if not_exist_name_ref.len() == 0 && !outer_exists { "" } else { "\npub " };
-        text = text.replace("\n", "\n    ");
+        text = text.replace('\n', "\n    ");
         text = format!("{vis}mod {name_ref} {{{text}\n}}");
     }
-    Some(text.replace("\n", &format!("\n{indent}")))
+    Some(text.replace('\n', &format!("\n{indent}")))
 }
 
 fn target_data_for_generate_constant(
@@ -131,7 +131,7 @@ fn target_data_for_generate_constant(
 
             let siblings_has_newline = l_curly_token
                 .siblings_with_tokens(Direction::Next)
-                .find(|it| it.kind() == SyntaxKind::WHITESPACE && it.to_string().contains("\n"))
+                .find(|it| it.kind() == SyntaxKind::WHITESPACE && it.to_string().contains('\n'))
                 .is_some();
             let post_string =
                 if siblings_has_newline { format!("{indent}") } else { format!("\n{indent}") };
diff --git a/crates/ide-assists/src/handlers/reorder_fields.rs b/crates/ide-assists/src/handlers/reorder_fields.rs
index 58dcaf9a221..cd977a68a67 100644
--- a/crates/ide-assists/src/handlers/reorder_fields.rs
+++ b/crates/ide-assists/src/handlers/reorder_fields.rs
@@ -20,9 +20,10 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
 // const test: Foo = Foo {foo: 1, bar: 0}
 // ```
 pub(crate) fn reorder_fields(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
-    let record = ctx.find_node_at_offset::<Either<ast::RecordExpr, ast::RecordPat>>()?;
+    let path = ctx.find_node_at_offset::<ast::Path>()?;
+    let record =
+        path.syntax().parent().and_then(<Either<ast::RecordExpr, ast::RecordPat>>::cast)?;
 
-    let path = record.as_ref().either(|it| it.path(), |it| it.path())?;
     let ranks = compute_fields_ranks(&path, ctx)?;
     let get_rank_of_field =
         |of: Option<_>| *ranks.get(&of.unwrap_or_default()).unwrap_or(&usize::MAX);
diff --git a/crates/ide-assists/src/handlers/unwrap_block.rs b/crates/ide-assists/src/handlers/unwrap_block.rs
index 33b19a354b9..939055f148c 100644
--- a/crates/ide-assists/src/handlers/unwrap_block.rs
+++ b/crates/ide-assists/src/handlers/unwrap_block.rs
@@ -51,15 +51,11 @@ pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
         let replaced = match list.syntax().last_child() {
             Some(last) => {
                 let stmts: Vec<ast::Stmt> = list.statements().collect();
-                let initializer = ast::Expr::cast(last.clone())?;
+                let initializer = ast::Expr::cast(last)?;
                 let let_stmt = make::let_stmt(pattern, ty, Some(initializer));
                 if stmts.len() > 0 {
                     let block = make::block_expr(stmts, None);
-                    format!(
-                        "{}\n    {}",
-                        update_expr_string(block.to_string()),
-                        let_stmt.to_string()
-                    )
+                    format!("{}\n    {}", update_expr_string(block.to_string()), let_stmt)
                 } else {
                     let_stmt.to_string()
                 }
diff --git a/crates/ide-assists/src/tests/generated.rs b/crates/ide-assists/src/tests/generated.rs
index aff11367de9..dd8705d797c 100644
--- a/crates/ide-assists/src/tests/generated.rs
+++ b/crates/ide-assists/src/tests/generated.rs
@@ -439,7 +439,7 @@ fn doctest_convert_match_to_let_else() {
         r#####"
 //- minicore: option
 fn foo(opt: Option<()>) {
-    let val = $0match opt {
+    let val$0 = match opt {
         Some(it) => it,
         None => return,
     };
diff --git a/crates/ide-diagnostics/src/handlers/unlinked_file.rs b/crates/ide-diagnostics/src/handlers/unlinked_file.rs
index 3d45a75913a..145e18c5c48 100644
--- a/crates/ide-diagnostics/src/handlers/unlinked_file.rs
+++ b/crates/ide-diagnostics/src/handlers/unlinked_file.rs
@@ -92,7 +92,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, file_id: FileId) -> Option<Vec<Assist>> {
     // if we aren't adding to a crate root, walk backwards such that we support `#[path = ...]` overrides if possible
 
     // build all parent paths of the form `../module_name/mod.rs` and `../module_name.rs`
-    let paths = iter::successors(Some(parent.clone()), |prev| prev.parent()).filter_map(|path| {
+    let paths = iter::successors(Some(parent), |prev| prev.parent()).filter_map(|path| {
         let parent = path.parent()?;
         let (name, _) = path.name_and_extension()?;
         Some(([parent.join(&format!("{name}.rs"))?, path.join("mod.rs")?], name.to_owned()))
diff --git a/crates/rust-analyzer/src/cli/scip.rs b/crates/rust-analyzer/src/cli/scip.rs
index 3e5e40750e9..1c848090b6a 100644
--- a/crates/rust-analyzer/src/cli/scip.rs
+++ b/crates/rust-analyzer/src/cli/scip.rs
@@ -66,7 +66,6 @@ impl flags::Scip {
                     .as_os_str()
                     .to_str()
                     .ok_or(anyhow::anyhow!("Unable to normalize project_root path"))?
-                    .to_string()
             ),
             text_document_encoding: scip_types::TextEncoding::UTF8.into(),
             special_fields: Default::default(),
@@ -212,7 +211,7 @@ fn new_descriptor_str(
 
 fn new_descriptor(name: Name, suffix: scip_types::descriptor::Suffix) -> scip_types::Descriptor {
     let mut name = name.to_string();
-    if name.contains("'") {
+    if name.contains('\'') {
         name = format!("`{name}`");
     }
 
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 7d97b69f8ea..2b9dfecceff 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -279,7 +279,7 @@ fn completion_item(
 
     let mut lsp_item = lsp_types::CompletionItem {
         label: item.label.to_string(),
-        detail: item.detail.map(|it| it.to_string()),
+        detail: item.detail,
         filter_text: Some(lookup),
         kind: Some(completion_item_kind(item.kind)),
         text_edit: Some(text_edit),