migrate_replace_derive_with_manual_impl
diff --git a/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/crates/ide-assists/src/handlers/add_missing_impl_members.rs
index d47e4b7..7459f37 100644
--- a/crates/ide-assists/src/handlers/add_missing_impl_members.rs
+++ b/crates/ide-assists/src/handlers/add_missing_impl_members.rs
@@ -158,7 +158,6 @@
             &target_scope,
         );
 
-        let mut editor = edit.make_editor(impl_def.syntax());
         if let Some(cap) = ctx.config.snippet_cap {
             let mut placeholder = None;
             if let DefaultMethods::No = mode {
@@ -172,13 +171,11 @@
                     ) && let Some(func_body) = func.body()
                     {
                         ted::replace(func_body.syntax(), body.syntax());
-                    } else {
-                        if let Some(m) = func.syntax().descendants().find_map(ast::MacroCall::cast)
-                        {
-                            if m.syntax().text() == "todo!()" {
-                                placeholder = Some(m);
-                            }
-                        }
+                    } else if let Some(m) =
+                        func.syntax().descendants().find_map(ast::MacroCall::cast)
+                        && m.syntax().text() == "todo!()"
+                    {
+                        placeholder = Some(m);
                     }
                 }
             }
diff --git a/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
index b7b8ae1..2f979b7 100644
--- a/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -5,12 +5,12 @@
     SyntaxKind::WHITESPACE,
     T,
     ast::{self, AstNode, HasName, make},
-    ted::{self, Position},
+    syntax_editor::{Position, SyntaxEditor},
 };
 
 use crate::{
     AssistConfig, AssistId,
-    assist_context::{AssistContext, Assists, SourceChangeBuilder},
+    assist_context::{AssistContext, Assists},
     utils::{
         DefaultMethods, IgnoreAssocItems, add_trait_assoc_items_to_impl, filter_assoc_items,
         gen_trait_fn_body, generate_trait_impl,
@@ -126,9 +126,9 @@
     let label = format!("Convert to manual `impl {replace_trait_path} for {annotated_name}`");
 
     acc.add(AssistId::refactor("replace_derive_with_manual_impl"), label, target, |builder| {
-        let insert_after = ted::Position::after(builder.make_mut(adt.clone()).syntax());
+        let insert_after = Position::after(adt.syntax());
         let impl_is_unsafe = trait_.map(|s| s.is_unsafe(ctx.db())).unwrap_or(false);
-        let impl_def_with_items = impl_def_from_trait(
+        let impl_def = impl_def_from_trait(
             &ctx.sema,
             ctx.config,
             adt,
@@ -137,39 +137,23 @@
             replace_trait_path,
             impl_is_unsafe,
         );
-        update_attribute(builder, old_derives, old_tree, old_trait_path, attr);
+
+        let mut editor = builder.make_editor(attr.syntax());
+        update_attribute(&mut editor, old_derives, old_tree, old_trait_path, attr);
 
         let trait_path = make::ty_path(replace_trait_path.clone());
 
-        match (ctx.config.snippet_cap, impl_def_with_items) {
-            (None, None) => {
-                let impl_def = generate_trait_impl(impl_is_unsafe, adt, trait_path);
+        let (impl_def, first_assoc_item) = if let Some(impl_def) = impl_def {
+            (
+                impl_def.clone(),
+                impl_def.assoc_item_list().and_then(|list| list.assoc_items().next()),
+            )
+        } else {
+            (generate_trait_impl(impl_is_unsafe, adt, trait_path), None)
+        };
 
-                ted::insert_all(
-                    insert_after,
-                    vec![make::tokens::blank_line().into(), impl_def.syntax().clone().into()],
-                );
-            }
-            (None, Some((impl_def, _))) => {
-                ted::insert_all(
-                    insert_after,
-                    vec![make::tokens::blank_line().into(), impl_def.syntax().clone().into()],
-                );
-            }
-            (Some(cap), None) => {
-                let impl_def = generate_trait_impl(impl_is_unsafe, adt, trait_path);
-
-                if let Some(l_curly) = impl_def.assoc_item_list().and_then(|it| it.l_curly_token())
-                {
-                    builder.add_tabstop_after_token(cap, l_curly);
-                }
-
-                ted::insert_all(
-                    insert_after,
-                    vec![make::tokens::blank_line().into(), impl_def.syntax().clone().into()],
-                );
-            }
-            (Some(cap), Some((impl_def, first_assoc_item))) => {
+        if let Some(cap) = ctx.config.snippet_cap {
+            if let Some(first_assoc_item) = first_assoc_item {
                 if let ast::AssocItem::Fn(ref func) = first_assoc_item
                     && let Some(m) = func.syntax().descendants().find_map(ast::MacroCall::cast)
                     && m.syntax().text() == "todo!()"
@@ -180,13 +164,18 @@
                     // If we haven't already added a snippet, add a tabstop before the generated function
                     builder.add_tabstop_before(cap, first_assoc_item);
                 }
-
-                ted::insert_all(
-                    insert_after,
-                    vec![make::tokens::blank_line().into(), impl_def.syntax().clone().into()],
-                );
+            } else if let Some(l_curly) =
+                impl_def.assoc_item_list().and_then(|it| it.l_curly_token())
+            {
+                builder.add_tabstop_after_token(cap, l_curly);
             }
-        };
+        }
+
+        editor.insert_all(
+            insert_after,
+            vec![make::tokens::blank_line().into(), impl_def.syntax().clone().into()],
+        );
+        builder.add_file_edits(ctx.vfs_file_id(), editor);
     })
 }
 
@@ -198,7 +187,7 @@
     trait_: Option<hir::Trait>,
     trait_path: &ast::Path,
     impl_is_unsafe: bool,
-) -> Option<(ast::Impl, ast::AssocItem)> {
+) -> Option<ast::Impl> {
     let trait_ = trait_?;
     let target_scope = sema.scope(annotated_name.syntax())?;
 
@@ -217,23 +206,25 @@
     }
     let impl_def = generate_trait_impl(impl_is_unsafe, adt, make::ty_path(trait_path.clone()));
 
-    let first_assoc_item =
+    let _ =
         add_trait_assoc_items_to_impl(sema, config, &trait_items, trait_, &impl_def, &target_scope);
-
+    let impl_def = impl_def.clone_subtree();
+    let mut editor = SyntaxEditor::new(impl_def.syntax().clone());
+    let first_assoc_item = impl_def.assoc_item_list().and_then(|item| item.assoc_items().next())?;
     // Generate a default `impl` function body for the derived trait.
     if let ast::AssocItem::Fn(ref func) = first_assoc_item {
         if let Some(body) = gen_trait_fn_body(func, trait_path, adt, None)
             && let Some(func_body) = func.body()
         {
-            ted::replace(func_body.syntax(), body.syntax());
+            editor.replace(func_body.syntax(), body.syntax());
         }
     };
-
-    Some((impl_def, first_assoc_item))
+    let impl_def = ast::Impl::cast(editor.finish().new_root().clone())?;
+    Some(impl_def)
 }
 
 fn update_attribute(
-    builder: &mut SourceChangeBuilder,
+    editor: &mut SyntaxEditor,
     old_derives: &[ast::Path],
     old_tree: &ast::TokenTree,
     old_trait_path: &ast::Path,
@@ -246,8 +237,6 @@
     let has_more_derives = !new_derives.is_empty();
 
     if has_more_derives {
-        let old_tree = builder.make_mut(old_tree.clone());
-
         // Make the paths into flat lists of tokens in a vec
         let tt = new_derives.iter().map(|path| path.syntax().clone()).map(|node| {
             node.descendants_with_tokens()
@@ -262,18 +251,17 @@
         let tt = tt.collect::<Vec<_>>();
 
         let new_tree = make::token_tree(T!['('], tt).clone_for_update();
-        ted::replace(old_tree.syntax(), new_tree.syntax());
+        editor.replace(old_tree.syntax(), new_tree.syntax());
     } else {
         // Remove the attr and any trailing whitespace
-        let attr = builder.make_mut(attr.clone());
 
         if let Some(line_break) =
             attr.syntax().next_sibling_or_token().filter(|t| t.kind() == WHITESPACE)
         {
-            ted::remove(line_break)
+            editor.delete(line_break)
         }
 
-        ted::remove(attr.syntax())
+        editor.delete(attr.syntax())
     }
 }