Unnamed repository; edit this file 'description' to name the repository.
introduce interior mutability to SyntaxEditor to let go of &mut usage
bit-aloo 6 weeks ago
parent 434895f · commit 1573144
-rw-r--r--crates/syntax/src/ast/edit.rs27
-rw-r--r--crates/syntax/src/syntax_editor.rs128
-rw-r--r--crates/syntax/src/syntax_editor/edit_algo.rs4
-rw-r--r--crates/syntax/src/syntax_editor/edits.rs50
4 files changed, 104 insertions, 105 deletions
diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs
index ae1293fb2f..b20aa90d06 100644
--- a/crates/syntax/src/ast/edit.rs
+++ b/crates/syntax/src/ast/edit.rs
@@ -108,7 +108,7 @@ impl IndentLevel {
}
pub(super) fn clone_increase_indent(self, node: &SyntaxNode) -> SyntaxNode {
- let (mut editor, node) = SyntaxEditor::new(node.clone());
+ let (editor, node) = SyntaxEditor::new(node.clone());
let tokens = node
.preorder_with_tokens()
.filter_map(|event| match event {
@@ -142,7 +142,7 @@ impl IndentLevel {
}
pub(super) fn clone_decrease_indent(self, node: &SyntaxNode) -> SyntaxNode {
- let (mut editor, node) = SyntaxEditor::new(node.clone());
+ let (editor, node) = SyntaxEditor::new(node.clone());
let tokens = node
.preorder_with_tokens()
.filter_map(|event| match event {
@@ -198,11 +198,8 @@ pub trait AstNodeEdit: AstNode + Clone + Sized {
impl<N: AstNode + Clone> AstNodeEdit for N {}
impl ast::IdentPat {
- pub fn set_pat(
- &self,
- pat: Option<ast::Pat>,
- syntax_editor: &mut SyntaxEditor,
- ) -> ast::IdentPat {
+ pub fn set_pat(&self, pat: Option<ast::Pat>, editor: &SyntaxEditor) -> ast::IdentPat {
+ let make = editor.make();
match pat {
None => {
if let Some(at_token) = self.at_token() {
@@ -212,7 +209,7 @@ impl ast::IdentPat {
.pat()
.map(|it| it.syntax().clone().into())
.unwrap_or_else(|| at_token.into());
- syntax_editor.delete_all(start..=end);
+ editor.delete_all(start..=end);
// Remove any trailing ws
if let Some(last) =
@@ -225,28 +222,28 @@ impl ast::IdentPat {
Some(pat) => {
if let Some(old_pat) = self.pat() {
// Replace existing pattern
- syntax_editor.replace(old_pat.syntax(), pat.syntax())
+ editor.replace(old_pat.syntax(), pat.syntax())
} else if let Some(at_token) = self.at_token() {
// Have an `@` token but not a pattern yet
- syntax_editor.insert(Position::after(at_token), pat.syntax());
+ editor.insert(Position::after(at_token), pat.syntax());
} else {
// Don't have an `@`, should have a name
let name = self.name().unwrap();
let elements = vec![
- syntax_editor.make().whitespace(" ").into(),
- syntax_editor.make().token(T![@]).into(),
- syntax_editor.make().whitespace(" ").into(),
+ make.whitespace(" ").into(),
+ make.token(T![@]).into(),
+ make.whitespace(" ").into(),
pat.syntax().clone().into(),
];
if self.syntax().parent().is_none() {
- let (mut local, local_self) = SyntaxEditor::with_ast_node(self);
+ let (local, local_self) = SyntaxEditor::with_ast_node(self);
let local_name = local_self.name().unwrap();
local.insert_all(Position::after(local_name.syntax()), elements);
let edit = local.finish();
return ast::IdentPat::cast(edit.new_root().clone()).unwrap();
} else {
- syntax_editor.insert_all(Position::after(name.syntax()), elements);
+ editor.insert_all(Position::after(name.syntax()), elements);
}
}
}
diff --git a/crates/syntax/src/syntax_editor.rs b/crates/syntax/src/syntax_editor.rs
index 4c20dc7a15..b2bd10b354 100644
--- a/crates/syntax/src/syntax_editor.rs
+++ b/crates/syntax/src/syntax_editor.rs
@@ -5,6 +5,7 @@
//! [`SyntaxEditor`]: https://github.com/dotnet/roslyn/blob/43b0b05cc4f492fd5de00f6f6717409091df8daa/src/Workspaces/Core/Portable/Editing/SyntaxEditor.cs
use std::{
+ cell::RefCell,
fmt, iter,
num::NonZeroU32,
ops::RangeInclusive,
@@ -29,8 +30,8 @@ pub use mapping::{SyntaxMapping, SyntaxMappingBuilder};
#[derive(Debug)]
pub struct SyntaxEditor {
root: SyntaxNode,
- changes: Vec<Change>,
- annotations: Vec<(SyntaxElement, SyntaxAnnotation)>,
+ changes: RefCell<Vec<Change>>,
+ annotations: RefCell<Vec<(SyntaxElement, SyntaxAnnotation)>>,
make: SyntaxFactory,
}
@@ -50,8 +51,8 @@ impl SyntaxEditor {
let editor = Self {
root: root.clone(),
- changes: Vec::new(),
- annotations: Vec::new(),
+ changes: RefCell::new(Vec::new()),
+ annotations: RefCell::new(Vec::new()),
make: SyntaxFactory::with_mappings(),
};
@@ -72,20 +73,17 @@ impl SyntaxEditor {
&self.make
}
- pub fn add_annotation(&mut self, element: impl Element, annotation: SyntaxAnnotation) {
- self.annotations.push((element.syntax_element(), annotation))
+ pub fn add_annotation(&self, element: impl Element, annotation: SyntaxAnnotation) {
+ self.annotations.borrow_mut().push((element.syntax_element(), annotation))
}
- pub fn add_annotation_all(
- &mut self,
- elements: Vec<impl Element>,
- annotation: SyntaxAnnotation,
- ) {
+ pub fn add_annotation_all(&self, elements: Vec<impl Element>, annotation: SyntaxAnnotation) {
self.annotations
+ .borrow_mut()
.extend(elements.into_iter().map(|e| e.syntax_element()).zip(iter::repeat(annotation)));
}
- pub fn merge(&mut self, mut other: SyntaxEditor) {
+ pub fn merge(&self, other: SyntaxEditor) {
debug_assert!(
self.root == other.root || other.root.ancestors().any(|node| node == self.root),
"{:?} is not in the same tree as {:?}",
@@ -93,32 +91,28 @@ impl SyntaxEditor {
self.root
);
- self.changes.append(&mut other.changes);
+ self.changes.borrow_mut().append(&mut other.changes.into_inner());
if let Some(mut m) = self.make.mappings() {
m.merge(other.make.take());
}
- self.annotations.append(&mut other.annotations);
+ self.annotations.borrow_mut().append(&mut other.annotations.into_inner());
}
- pub fn insert(&mut self, position: Position, element: impl Element) {
+ pub fn insert(&self, position: Position, element: impl Element) {
debug_assert!(is_ancestor_or_self(&position.parent(), &self.root));
- self.changes.push(Change::Insert(position, element.syntax_element()))
+ self.changes.borrow_mut().push(Change::Insert(position, element.syntax_element()))
}
- pub fn insert_all(&mut self, position: Position, elements: Vec<SyntaxElement>) {
+ pub fn insert_all(&self, position: Position, elements: Vec<SyntaxElement>) {
debug_assert!(is_ancestor_or_self(&position.parent(), &self.root));
- self.changes.push(Change::InsertAll(position, elements))
+ self.changes.borrow_mut().push(Change::InsertAll(position, elements))
}
- pub fn insert_with_whitespace(&mut self, position: Position, element: impl Element) {
+ pub fn insert_with_whitespace(&self, position: Position, element: impl Element) {
self.insert_all_with_whitespace(position, vec![element.syntax_element()])
}
- pub fn insert_all_with_whitespace(
- &mut self,
- position: Position,
- mut elements: Vec<SyntaxElement>,
- ) {
+ pub fn insert_all_with_whitespace(&self, position: Position, mut elements: Vec<SyntaxElement>) {
if let Some(first) = elements.first()
&& let Some(ws) = ws_before(&position, first, &self.make)
{
@@ -132,50 +126,52 @@ impl SyntaxEditor {
self.insert_all(position, elements)
}
- pub fn delete(&mut self, element: impl Element) {
+ pub fn delete(&self, element: impl Element) {
let element = element.syntax_element();
debug_assert!(is_ancestor_or_self_of_element(&element, &self.root));
debug_assert!(
!matches!(&element, SyntaxElement::Node(node) if node == &self.root),
"should not delete root node"
);
- self.changes.push(Change::Replace(element.syntax_element(), None));
+ self.changes.borrow_mut().push(Change::Replace(element.syntax_element(), None));
}
- pub fn delete_all(&mut self, range: RangeInclusive<SyntaxElement>) {
+ pub fn delete_all(&self, range: RangeInclusive<SyntaxElement>) {
if range.start() == range.end() {
self.delete(range.start());
return;
}
debug_assert!(is_ancestor_or_self_of_element(range.start(), &self.root));
- self.changes.push(Change::ReplaceAll(range, Vec::new()))
+ self.changes.borrow_mut().push(Change::ReplaceAll(range, Vec::new()))
}
- pub fn replace(&mut self, old: impl Element, new: impl Element) {
+ pub fn replace(&self, old: impl Element, new: impl Element) {
let old = old.syntax_element();
debug_assert!(is_ancestor_or_self_of_element(&old, &self.root));
- self.changes.push(Change::Replace(old.syntax_element(), Some(new.syntax_element())));
+ self.changes
+ .borrow_mut()
+ .push(Change::Replace(old.syntax_element(), Some(new.syntax_element())));
}
- pub fn replace_with_many(&mut self, old: impl Element, new: Vec<SyntaxElement>) {
+ pub fn replace_with_many(&self, old: impl Element, new: Vec<SyntaxElement>) {
let old = old.syntax_element();
debug_assert!(is_ancestor_or_self_of_element(&old, &self.root));
debug_assert!(
!(matches!(&old, SyntaxElement::Node(node) if node == &self.root) && new.len() > 1),
"cannot replace root node with many elements"
);
- self.changes.push(Change::ReplaceWithMany(old.syntax_element(), new));
+ self.changes.borrow_mut().push(Change::ReplaceWithMany(old.syntax_element(), new));
}
- pub fn replace_all(&mut self, range: RangeInclusive<SyntaxElement>, new: Vec<SyntaxElement>) {
+ pub fn replace_all(&self, range: RangeInclusive<SyntaxElement>, new: Vec<SyntaxElement>) {
if range.start() == range.end() {
self.replace_with_many(range.start(), new);
return;
}
debug_assert!(is_ancestor_or_self_of_element(range.start(), &self.root));
- self.changes.push(Change::ReplaceAll(range, new))
+ self.changes.borrow_mut().push(Change::ReplaceAll(range, new))
}
pub fn finish(self) -> SyntaxEdit {
@@ -555,7 +551,8 @@ mod tests {
.into(),
);
- let (mut editor, root) = SyntaxEditor::with_ast_node(&root);
+ let (editor, root) = SyntaxEditor::with_ast_node(&root);
+ let make = editor.make();
let to_wrap = root.syntax().descendants().find_map(ast::TupleExpr::cast).unwrap();
let to_replace = root.syntax().descendants().find_map(ast::BinExpr::cast).unwrap();
@@ -567,11 +564,11 @@ mod tests {
editor.add_annotation(name.syntax(), placeholder_snippet);
editor.add_annotation(name_ref.syntax(), placeholder_snippet);
- let new_block = editor.make().block_expr(
+ let new_block = make.block_expr(
[editor
.make()
.let_stmt(
- editor.make().ident_pat(false, false, name.clone()).into(),
+ make.ident_pat(false, false, name.clone()).into(),
None,
Some(to_replace.clone().into()),
)
@@ -612,31 +609,28 @@ mod tests {
None,
);
- let (mut editor, root) = SyntaxEditor::with_ast_node(&root);
+ let (editor, root) = SyntaxEditor::with_ast_node(&root);
+ let make = editor.make();
let second_let = root.syntax().descendants().find_map(ast::LetStmt::cast).unwrap();
editor.insert(
Position::first_child_of(root.stmt_list().unwrap().syntax()),
- editor
- .make()
- .let_stmt(
- make::ext::simple_ident_pat(make::name("first")).into(),
- None,
- Some(make::expr_literal("1").into()),
- )
- .syntax(),
+ make.let_stmt(
+ make::ext::simple_ident_pat(make::name("first")).into(),
+ None,
+ Some(make::expr_literal("1").into()),
+ )
+ .syntax(),
);
editor.insert(
Position::after(second_let.syntax()),
- editor
- .make()
- .let_stmt(
- make::ext::simple_ident_pat(make::name("third")).into(),
- None,
- Some(make::expr_literal("3").into()),
- )
- .syntax(),
+ make.let_stmt(
+ make::ext::simple_ident_pat(make::name("third")).into(),
+ None,
+ Some(make::expr_literal("3").into()),
+ )
+ .syntax(),
);
let edit = editor.finish();
@@ -666,22 +660,22 @@ mod tests {
),
);
- let (mut editor, root) = SyntaxEditor::with_ast_node(&root);
+ let (editor, root) = SyntaxEditor::with_ast_node(&root);
+ let make = editor.make();
let inner_block =
root.syntax().descendants().flat_map(ast::BlockExpr::cast).nth(1).unwrap();
let second_let = root.syntax().descendants().find_map(ast::LetStmt::cast).unwrap();
- let new_block_expr =
- editor.make().block_expr([], Some(ast::Expr::BlockExpr(inner_block.clone())));
+ let new_block_expr = make.block_expr([], Some(ast::Expr::BlockExpr(inner_block.clone())));
- let first_let = editor.make().let_stmt(
+ let first_let = make.let_stmt(
make::ext::simple_ident_pat(make::name("first")).into(),
None,
Some(make::expr_literal("1").into()),
);
- let third_let = editor.make().let_stmt(
+ let third_let = make.let_stmt(
make::ext::simple_ident_pat(make::name("third")).into(),
None,
Some(make::expr_literal("3").into()),
@@ -719,14 +713,14 @@ mod tests {
None,
);
- let (mut editor, root) = SyntaxEditor::with_ast_node(&root);
+ let (editor, root) = SyntaxEditor::with_ast_node(&root);
+ let make = editor.make();
let inner_block = root;
- let new_block_expr =
- editor.make().block_expr([], Some(ast::Expr::BlockExpr(inner_block.clone())));
+ let new_block_expr = make.block_expr([], Some(ast::Expr::BlockExpr(inner_block.clone())));
- let first_let = editor.make().let_stmt(
+ let first_let = make.let_stmt(
make::ext::simple_ident_pat(make::name("first")).into(),
None,
Some(make::expr_literal("1").into()),
@@ -766,7 +760,7 @@ mod tests {
false,
);
- let (mut editor, parent_fn) = SyntaxEditor::with_ast_node(&parent_fn);
+ let (editor, parent_fn) = SyntaxEditor::with_ast_node(&parent_fn);
if let Some(ret_ty) = parent_fn.ret_type() {
editor.delete(ret_ty.syntax().clone());
@@ -793,7 +787,7 @@ mod tests {
let arg_list =
make::arg_list([make::expr_literal("1").into(), make::expr_literal("2").into()]);
- let (mut editor, arg_list) = SyntaxEditor::with_ast_node(&arg_list);
+ let (editor, arg_list) = SyntaxEditor::with_ast_node(&arg_list);
let target_expr = make::token(parser::SyntaxKind::UNDERSCORE);
@@ -812,7 +806,7 @@ mod tests {
let arg_list =
make::arg_list([make::expr_literal("1").into(), make::expr_literal("2").into()]);
- let (mut editor, arg_list) = SyntaxEditor::with_ast_node(&arg_list);
+ let (editor, arg_list) = SyntaxEditor::with_ast_node(&arg_list);
let target_expr = make::expr_literal("3").clone_for_update();
@@ -831,7 +825,7 @@ mod tests {
let arg_list =
make::arg_list([make::expr_literal("1").into(), make::expr_literal("2").into()]);
- let (mut editor, arg_list) = SyntaxEditor::with_ast_node(&arg_list);
+ let (editor, arg_list) = SyntaxEditor::with_ast_node(&arg_list);
let target_expr = make::ext::expr_unit().clone_for_update();
diff --git a/crates/syntax/src/syntax_editor/edit_algo.rs b/crates/syntax/src/syntax_editor/edit_algo.rs
index 4e08daba7b..27ea03ec09 100644
--- a/crates/syntax/src/syntax_editor/edit_algo.rs
+++ b/crates/syntax/src/syntax_editor/edit_algo.rs
@@ -35,7 +35,9 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit {
// - changed nodes become part of the changed node set (useful for the formatter to only change those parts)
// - Propagate annotations
- let SyntaxEditor { root, mut changes, annotations, make } = editor;
+ let SyntaxEditor { root, changes, annotations, make } = editor;
+ let mut changes = changes.into_inner();
+ let annotations = annotations.into_inner();
let mappings = make.take();
let mut node_depths = FxHashMap::<SyntaxNode, usize>::default();
diff --git a/crates/syntax/src/syntax_editor/edits.rs b/crates/syntax/src/syntax_editor/edits.rs
index 1718f1a51c..62fd7db8d3 100644
--- a/crates/syntax/src/syntax_editor/edits.rs
+++ b/crates/syntax/src/syntax_editor/edits.rs
@@ -12,20 +12,21 @@ pub trait GetOrCreateWhereClause: ast::HasGenericParams {
fn get_or_create_where_clause(
&self,
- editor: &mut SyntaxEditor,
+ editor: &SyntaxEditor,
new_preds: impl Iterator<Item = ast::WherePred>,
) {
+ let make = editor.make();
let existing = self.where_clause();
let all_preds: Vec<_> =
existing.iter().flat_map(|wc| wc.predicates()).chain(new_preds).collect();
- let new_where = editor.make().where_clause(all_preds);
+ let new_where = make.where_clause(all_preds);
if let Some(existing) = &existing {
editor.replace(existing.syntax(), new_where.syntax());
} else if let Some(pos) = self.where_clause_position() {
editor.insert_all(
pos,
- vec![editor.make().whitespace(" ").into(), new_where.syntax().clone().into()],
+ vec![make.whitespace(" ").into(), new_where.syntax().clone().into()],
);
}
}
@@ -109,7 +110,7 @@ impl GetOrCreateWhereClause for ast::Enum {
impl SyntaxEditor {
/// Adds a new generic param to the function using `SyntaxEditor`
- pub fn add_generic_param(&mut self, function: &Fn, new_param: GenericParam) {
+ pub fn add_generic_param(&self, function: &Fn, new_param: GenericParam) {
match function.generic_param_list() {
Some(generic_param_list) => match generic_param_list.generic_params().last() {
Some(last_param) => {
@@ -173,7 +174,8 @@ impl SyntaxEditor {
}
}
-fn get_or_insert_comma_after(editor: &mut SyntaxEditor, syntax: &SyntaxNode) -> SyntaxToken {
+fn get_or_insert_comma_after(editor: &SyntaxEditor, syntax: &SyntaxNode) -> SyntaxToken {
+ let make = editor.make();
match syntax
.siblings_with_tokens(Direction::Next)
.filter_map(|it| it.into_token())
@@ -181,7 +183,7 @@ fn get_or_insert_comma_after(editor: &mut SyntaxEditor, syntax: &SyntaxNode) ->
{
Some(it) => it,
None => {
- let comma = editor.make().token(T![,]);
+ let comma = make.token(T![,]);
editor.insert(Position::after(syntax), &comma);
comma
}
@@ -193,7 +195,7 @@ impl ast::AssocItemList {
///
/// Attention! This function does align the first line of `item` with respect to `self`,
/// but it does _not_ change indentation of other lines (if any).
- pub fn add_items(&self, editor: &mut SyntaxEditor, items: Vec<ast::AssocItem>) {
+ pub fn add_items(&self, editor: &SyntaxEditor, items: Vec<ast::AssocItem>) {
let (indent, position, whitespace) = match self.assoc_items().last() {
Some(last_item) => (
IndentLevel::from_node(last_item.syntax()),
@@ -227,15 +229,16 @@ impl ast::AssocItemList {
impl ast::Impl {
pub fn get_or_create_assoc_item_list_with_editor(
&self,
- editor: &mut SyntaxEditor,
+ editor: &SyntaxEditor,
) -> ast::AssocItemList {
+ let make = editor.make();
if let Some(list) = self.assoc_item_list() {
list
} else {
- let list = editor.make().assoc_item_list_empty();
+ let list = make.assoc_item_list_empty();
editor.insert_all(
Position::last_child_of(self.syntax()),
- vec![editor.make().whitespace(" ").into(), list.syntax().clone().into()],
+ vec![make.whitespace(" ").into(), list.syntax().clone().into()],
);
list
}
@@ -243,7 +246,8 @@ impl ast::Impl {
}
impl ast::VariantList {
- pub fn add_variant(&self, editor: &mut SyntaxEditor, variant: &ast::Variant) {
+ pub fn add_variant(&self, editor: &SyntaxEditor, variant: &ast::Variant) {
+ let make = editor.make();
let (indent, position) = match self.variants().last() {
Some(last_item) => (
IndentLevel::from_node(last_item.syntax()),
@@ -258,16 +262,16 @@ impl ast::VariantList {
},
};
let elements: Vec<SyntaxElement> = vec![
- editor.make().whitespace(&format!("{}{indent}", "\n")).into(),
+ make.whitespace(&format!("{}{indent}", "\n")).into(),
variant.syntax().clone().into(),
- editor.make().token(T![,]).into(),
+ make.token(T![,]).into(),
];
editor.insert_all(position, elements);
}
}
impl ast::Fn {
- pub fn replace_or_insert_body(&self, editor: &mut SyntaxEditor, body: ast::BlockExpr) {
+ pub fn replace_or_insert_body(&self, editor: &SyntaxEditor, body: ast::BlockExpr) {
if let Some(old_body) = self.body() {
editor.replace(old_body.syntax(), body.syntax());
} else {
@@ -283,7 +287,8 @@ impl ast::Fn {
}
}
-fn normalize_ws_between_braces(editor: &mut SyntaxEditor, node: &SyntaxNode) -> Option<()> {
+fn normalize_ws_between_braces(editor: &SyntaxEditor, node: &SyntaxNode) -> Option<()> {
+ let make = editor.make();
let l = node
.children_with_tokens()
.filter_map(|it| it.into_token())
@@ -298,11 +303,11 @@ fn normalize_ws_between_braces(editor: &mut SyntaxEditor, node: &SyntaxNode) ->
match l.next_sibling_or_token() {
Some(ws) if ws.kind() == SyntaxKind::WHITESPACE => {
if ws.next_sibling_or_token()?.into_token()? == r {
- editor.replace(ws, editor.make().whitespace(&format!("\n{indent}")));
+ editor.replace(ws, make.whitespace(&format!("\n{indent}")));
}
}
Some(ws) if ws.kind() == T!['}'] => {
- editor.insert(Position::after(l), editor.make().whitespace(&format!("\n{indent}")));
+ editor.insert(Position::after(l), make.whitespace(&format!("\n{indent}")));
}
_ => (),
}
@@ -310,11 +315,11 @@ fn normalize_ws_between_braces(editor: &mut SyntaxEditor, node: &SyntaxNode) ->
}
pub trait Removable: AstNode {
- fn remove(&self, editor: &mut SyntaxEditor);
+ fn remove(&self, editor: &SyntaxEditor);
}
impl Removable for ast::TypeBoundList {
- fn remove(&self, editor: &mut SyntaxEditor) {
+ fn remove(&self, editor: &SyntaxEditor) {
match self.syntax().siblings_with_tokens(Direction::Prev).find(|it| it.kind() == T![:]) {
Some(colon) => editor.delete_all(colon..=self.syntax().clone().into()),
None => editor.delete(self.syntax()),
@@ -323,7 +328,8 @@ impl Removable for ast::TypeBoundList {
}
impl Removable for ast::Use {
- fn remove(&self, editor: &mut SyntaxEditor) {
+ fn remove(&self, editor: &SyntaxEditor) {
+ let make = editor.make();
let next_ws = self
.syntax()
.next_sibling_or_token()
@@ -335,7 +341,7 @@ impl Removable for ast::Use {
if rest.is_empty() {
editor.delete(next_ws.syntax());
} else {
- editor.replace(next_ws.syntax(), editor.make().whitespace(rest));
+ editor.replace(next_ws.syntax(), make.whitespace(rest));
}
}
}
@@ -345,7 +351,7 @@ impl Removable for ast::Use {
}
impl Removable for ast::UseTree {
- fn remove(&self, editor: &mut SyntaxEditor) {
+ fn remove(&self, editor: &SyntaxEditor) {
for dir in [Direction::Next, Direction::Prev] {
if let Some(next_use_tree) = neighbor(self, dir) {
let separators = self