Skip to content

Commit 3c327c7

Browse files
Merge pull request #22036 from Shourya742/2026-04-14-remove-set-path
Replace set path usage with set_path_with_editor
2 parents fed32aa + db9a4db commit 3c327c7

4 files changed

Lines changed: 101 additions & 158 deletions

File tree

crates/ide-assists/src/handlers/convert_let_else_to_match.rs

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use syntax::ast::RangeItem;
33
use syntax::ast::edit::AstNodeEdit;
44
use syntax::ast::syntax_factory::SyntaxFactory;
55
use syntax::ast::{self, AstNode, HasName, LetStmt, Pat};
6+
use syntax::syntax_editor::SyntaxEditor;
67

78
use crate::{AssistContext, AssistId, Assists};
89

@@ -25,12 +26,15 @@ use crate::{AssistContext, AssistId, Assists};
2526
// }
2627
// ```
2728
pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
29+
let root = ctx.source_file().syntax().clone();
30+
let (mut editor, _) = SyntaxEditor::new(root);
2831
// Should focus on the `else` token to trigger
2932
let let_stmt = ctx
3033
.find_token_syntax_at_offset(T![else])
3134
.and_then(|it| it.parent()?.parent())
3235
.or_else(|| ctx.find_token_syntax_at_offset(T![let])?.parent())?;
3336
let let_stmt = LetStmt::cast(let_stmt)?;
37+
let make = SyntaxFactory::with_mappings();
3438
let else_block = let_stmt.let_else()?.block_expr()?;
3539
let else_expr = if else_block.statements().next().is_none()
3640
&& let Some(tail_expr) = else_block.tail_expr()
@@ -45,10 +49,8 @@ pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'
4549
return None;
4650
}
4751
let pat = let_stmt.pat()?;
48-
49-
let make = SyntaxFactory::with_mappings();
5052
let mut idents = Vec::default();
51-
let pat_without_mut = remove_mut_and_collect_idents(&make, &pat, &mut idents)?;
53+
let pat_without_mut = remove_mut_and_collect_idents(&make, &mut editor, &pat, &mut idents)?;
5254
let bindings = idents
5355
.into_iter()
5456
.filter_map(|ref pat| {
@@ -70,7 +72,7 @@ pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'
7072
},
7173
let_stmt.syntax().text_range(),
7274
|builder| {
73-
let mut editor = builder.make_editor(let_stmt.syntax());
75+
// let mut editor = builder.make_editor(let_stmt.syntax());
7476

7577
let binding_paths = bindings
7678
.iter()
@@ -124,6 +126,7 @@ pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'
124126

125127
fn remove_mut_and_collect_idents(
126128
make: &SyntaxFactory,
129+
editor: &mut SyntaxEditor,
127130
pat: &ast::Pat,
128131
acc: &mut Vec<ast::IdentPat>,
129132
) -> Option<ast::Pat> {
@@ -135,34 +138,40 @@ fn remove_mut_and_collect_idents(
135138
p.ref_token().is_some() && p.mut_token().is_some(),
136139
p.name()?,
137140
);
138-
if let Some(inner) = p.pat() {
139-
non_mut_pat.set_pat(remove_mut_and_collect_idents(make, &inner, acc));
140-
}
141+
let non_mut_pat = if let Some(inner) = p.pat() {
142+
non_mut_pat.set_pat(
143+
remove_mut_and_collect_idents(make, editor, &inner, acc),
144+
editor,
145+
make,
146+
)
147+
} else {
148+
non_mut_pat
149+
};
141150
non_mut_pat.into()
142151
}
143152
ast::Pat::BoxPat(p) => {
144-
make.box_pat(remove_mut_and_collect_idents(make, &p.pat()?, acc)?).into()
153+
make.box_pat(remove_mut_and_collect_idents(make, editor, &p.pat()?, acc)?).into()
145154
}
146155
ast::Pat::OrPat(p) => make
147156
.or_pat(
148157
p.pats()
149-
.map(|pat| remove_mut_and_collect_idents(make, &pat, acc))
158+
.map(|pat| remove_mut_and_collect_idents(make, editor, &pat, acc))
150159
.collect::<Option<Vec<_>>>()?,
151160
p.leading_pipe().is_some(),
152161
)
153162
.into(),
154163
ast::Pat::ParenPat(p) => {
155-
make.paren_pat(remove_mut_and_collect_idents(make, &p.pat()?, acc)?).into()
164+
make.paren_pat(remove_mut_and_collect_idents(make, editor, &p.pat()?, acc)?).into()
156165
}
157166
ast::Pat::RangePat(p) => make
158167
.range_pat(
159168
if let Some(start) = p.start() {
160-
Some(remove_mut_and_collect_idents(make, &start, acc)?)
169+
Some(remove_mut_and_collect_idents(make, editor, &start, acc)?)
161170
} else {
162171
None
163172
},
164173
if let Some(end) = p.end() {
165-
Some(remove_mut_and_collect_idents(make, &end, acc)?)
174+
Some(remove_mut_and_collect_idents(make, editor, &end, acc)?)
166175
} else {
167176
None
168177
},
@@ -175,13 +184,15 @@ fn remove_mut_and_collect_idents(
175184
p.record_pat_field_list()?
176185
.fields()
177186
.map(|field| {
178-
remove_mut_and_collect_idents(make, &field.pat()?, acc).map(|pat| {
179-
if let Some(name_ref) = field.name_ref() {
180-
make.record_pat_field(name_ref, pat)
181-
} else {
182-
make.record_pat_field_shorthand(pat)
183-
}
184-
})
187+
remove_mut_and_collect_idents(make, editor, &field.pat()?, acc).map(
188+
|pat| {
189+
if let Some(name_ref) = field.name_ref() {
190+
make.record_pat_field(name_ref, pat)
191+
} else {
192+
make.record_pat_field_shorthand(pat)
193+
}
194+
},
195+
)
185196
})
186197
.collect::<Option<Vec<_>>>()?,
187198
p.record_pat_field_list()?.rest_pat(),
@@ -194,28 +205,28 @@ fn remove_mut_and_collect_idents(
194205
acc.push(ident);
195206
p.clone().into()
196207
} else {
197-
make.ref_pat(remove_mut_and_collect_idents(make, &inner, acc)?).into()
208+
make.ref_pat(remove_mut_and_collect_idents(make, editor, &inner, acc)?).into()
198209
}
199210
}
200211
ast::Pat::SlicePat(p) => make
201212
.slice_pat(
202213
p.pats()
203-
.map(|pat| remove_mut_and_collect_idents(make, &pat, acc))
214+
.map(|pat| remove_mut_and_collect_idents(make, editor, &pat, acc))
204215
.collect::<Option<Vec<_>>>()?,
205216
)
206217
.into(),
207218
ast::Pat::TuplePat(p) => make
208219
.tuple_pat(
209220
p.fields()
210-
.map(|field| remove_mut_and_collect_idents(make, &field, acc))
221+
.map(|field| remove_mut_and_collect_idents(make, editor, &field, acc))
211222
.collect::<Option<Vec<_>>>()?,
212223
)
213224
.into(),
214225
ast::Pat::TupleStructPat(p) => make
215226
.tuple_struct_pat(
216227
p.path()?,
217228
p.fields()
218-
.map(|field| remove_mut_and_collect_idents(make, &field, acc))
229+
.map(|field| remove_mut_and_collect_idents(make, editor, &field, acc))
219230
.collect::<Option<Vec<_>>>()?,
220231
)
221232
.into(),

crates/ide-assists/src/handlers/destructure_tuple_binding.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,7 @@ impl AssignmentEdit {
226226
fn apply(self, syntax_editor: &mut SyntaxEditor, syntax_mapping: &SyntaxFactory) {
227227
// with sub_pattern: keep original tuple and add subpattern: `tup @ (_0, _1)`
228228
if self.in_sub_pattern {
229-
self.ident_pat.set_pat_with_editor(
230-
Some(self.tuple_pat.into()),
231-
syntax_editor,
232-
syntax_mapping,
233-
)
229+
self.ident_pat.set_pat(Some(self.tuple_pat.into()), syntax_editor, syntax_mapping);
234230
} else if self.is_shorthand_field {
235231
syntax_editor.insert(Position::after(self.ident_pat.syntax()), self.tuple_pat.syntax());
236232
syntax_editor

crates/syntax/src/ast/edit.rs

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
//! This module contains functions for editing syntax trees. As the trees are
22
//! immutable, all function here return a fresh copy of the tree, instead of
33
//! doing an in-place modification.
4+
use parser::T;
45
use std::{fmt, iter, ops};
56

67
use crate::{
7-
AstToken, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxToken,
8-
ast::{self, AstNode, make},
9-
syntax_editor::{SyntaxEditor, SyntaxMappingBuilder},
8+
AstToken, NodeOrToken, SyntaxElement,
9+
SyntaxKind::WHITESPACE,
10+
SyntaxNode, SyntaxToken,
11+
ast::{self, AstNode, HasName, make},
12+
syntax_editor::{Position, SyntaxEditor, SyntaxMappingBuilder},
1013
ted,
1114
};
1215

@@ -194,6 +197,65 @@ pub trait AstNodeEdit: AstNode + Clone + Sized {
194197

195198
impl<N: AstNode + Clone> AstNodeEdit for N {}
196199

200+
impl ast::IdentPat {
201+
pub fn set_pat(
202+
&self,
203+
pat: Option<ast::Pat>,
204+
syntax_editor: &mut SyntaxEditor,
205+
syntax_factory: &SyntaxFactory,
206+
) -> ast::IdentPat {
207+
match pat {
208+
None => {
209+
if let Some(at_token) = self.at_token() {
210+
// Remove `@ Pat`
211+
let start = at_token.clone().into();
212+
let end = self
213+
.pat()
214+
.map(|it| it.syntax().clone().into())
215+
.unwrap_or_else(|| at_token.into());
216+
syntax_editor.delete_all(start..=end);
217+
218+
// Remove any trailing ws
219+
if let Some(last) =
220+
self.syntax().last_token().filter(|it| it.kind() == WHITESPACE)
221+
{
222+
last.detach();
223+
}
224+
}
225+
}
226+
Some(pat) => {
227+
if let Some(old_pat) = self.pat() {
228+
// Replace existing pattern
229+
syntax_editor.replace(old_pat.syntax(), pat.syntax())
230+
} else if let Some(at_token) = self.at_token() {
231+
// Have an `@` token but not a pattern yet
232+
syntax_editor.insert(Position::after(at_token), pat.syntax());
233+
} else {
234+
// Don't have an `@`, should have a name
235+
let name = self.name().unwrap();
236+
let elements = vec![
237+
syntax_factory.whitespace(" ").into(),
238+
syntax_factory.token(T![@]).into(),
239+
syntax_factory.whitespace(" ").into(),
240+
pat.syntax().clone().into(),
241+
];
242+
243+
if self.syntax().parent().is_none() {
244+
let (mut local, local_self) = SyntaxEditor::with_ast_node(self);
245+
let local_name = local_self.name().unwrap();
246+
local.insert_all(Position::after(local_name.syntax()), elements);
247+
let edit = local.finish();
248+
return ast::IdentPat::cast(edit.new_root().clone()).unwrap();
249+
} else {
250+
syntax_editor.insert_all(Position::after(name.syntax()), elements);
251+
}
252+
}
253+
}
254+
}
255+
self.clone()
256+
}
257+
}
258+
197259
#[test]
198260
fn test_increase_indent() {
199261
let arm_list = {

0 commit comments

Comments
 (0)