diff options
Diffstat (limited to 'crates/ra_assists/src/auto_import.rs')
-rw-r--r-- | crates/ra_assists/src/auto_import.rs | 143 |
1 files changed, 76 insertions, 67 deletions
diff --git a/crates/ra_assists/src/auto_import.rs b/crates/ra_assists/src/auto_import.rs index f8f37e852..0eb4bdb62 100644 --- a/crates/ra_assists/src/auto_import.rs +++ b/crates/ra_assists/src/auto_import.rs | |||
@@ -12,25 +12,25 @@ use ra_syntax::{ | |||
12 | SyntaxNode, TextRange, T, | 12 | SyntaxNode, TextRange, T, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | fn collect_path_segments_raw<'a>( | 15 | fn collect_path_segments_raw( |
16 | segments: &mut Vec<&'a ast::PathSegment>, | 16 | segments: &mut Vec<ast::PathSegment>, |
17 | mut path: &'a ast::Path, | 17 | mut path: ast::Path, |
18 | ) -> Option<usize> { | 18 | ) -> Option<usize> { |
19 | let oldlen = segments.len(); | 19 | let oldlen = segments.len(); |
20 | loop { | 20 | loop { |
21 | let mut children = path.syntax().children_with_tokens(); | 21 | let mut children = path.syntax().children_with_tokens(); |
22 | let (first, second, third) = ( | 22 | let (first, second, third) = ( |
23 | children.next().map(|n| (n, n.kind())), | 23 | children.next().map(|n| (n.clone(), n.kind())), |
24 | children.next().map(|n| (n, n.kind())), | 24 | children.next().map(|n| (n.clone(), n.kind())), |
25 | children.next().map(|n| (n, n.kind())), | 25 | children.next().map(|n| (n.clone(), n.kind())), |
26 | ); | 26 | ); |
27 | match (first, second, third) { | 27 | match (first, second, third) { |
28 | (Some((subpath, PATH)), Some((_, T![::])), Some((segment, PATH_SEGMENT))) => { | 28 | (Some((subpath, PATH)), Some((_, T![::])), Some((segment, PATH_SEGMENT))) => { |
29 | path = ast::Path::cast(subpath.as_node()?)?; | 29 | path = ast::Path::cast(subpath.as_node()?.clone())?; |
30 | segments.push(ast::PathSegment::cast(segment.as_node()?)?); | 30 | segments.push(ast::PathSegment::cast(segment.as_node()?.clone())?); |
31 | } | 31 | } |
32 | (Some((segment, PATH_SEGMENT)), _, _) => { | 32 | (Some((segment, PATH_SEGMENT)), _, _) => { |
33 | segments.push(ast::PathSegment::cast(segment.as_node()?)?); | 33 | segments.push(ast::PathSegment::cast(segment.as_node()?.clone())?); |
34 | break; | 34 | break; |
35 | } | 35 | } |
36 | (_, _, _) => return None, | 36 | (_, _, _) => return None, |
@@ -60,7 +60,7 @@ fn fmt_segments_raw(segments: &[SmolStr], buf: &mut String) { | |||
60 | } | 60 | } |
61 | 61 | ||
62 | // Returns the numeber of common segments. | 62 | // Returns the numeber of common segments. |
63 | fn compare_path_segments(left: &[SmolStr], right: &[&ast::PathSegment]) -> usize { | 63 | fn compare_path_segments(left: &[SmolStr], right: &[ast::PathSegment]) -> usize { |
64 | left.iter().zip(right).filter(|(l, r)| compare_path_segment(l, r)).count() | 64 | left.iter().zip(right).filter(|(l, r)| compare_path_segment(l, r)).count() |
65 | } | 65 | } |
66 | 66 | ||
@@ -81,12 +81,12 @@ fn compare_path_segment_with_name(a: &SmolStr, b: &ast::Name) -> bool { | |||
81 | a == b.text() | 81 | a == b.text() |
82 | } | 82 | } |
83 | 83 | ||
84 | #[derive(Copy, Clone)] | 84 | #[derive(Clone)] |
85 | enum ImportAction<'a> { | 85 | enum ImportAction { |
86 | Nothing, | 86 | Nothing, |
87 | // Add a brand new use statement. | 87 | // Add a brand new use statement. |
88 | AddNewUse { | 88 | AddNewUse { |
89 | anchor: Option<&'a SyntaxNode>, // anchor node | 89 | anchor: Option<SyntaxNode>, // anchor node |
90 | add_after_anchor: bool, | 90 | add_after_anchor: bool, |
91 | }, | 91 | }, |
92 | 92 | ||
@@ -94,9 +94,9 @@ enum ImportAction<'a> { | |||
94 | AddNestedImport { | 94 | AddNestedImport { |
95 | // how may segments matched with the target path | 95 | // how may segments matched with the target path |
96 | common_segments: usize, | 96 | common_segments: usize, |
97 | path_to_split: &'a ast::Path, | 97 | path_to_split: ast::Path, |
98 | // the first segment of path_to_split we want to add into the new nested list | 98 | // the first segment of path_to_split we want to add into the new nested list |
99 | first_segment_to_split: Option<&'a ast::PathSegment>, | 99 | first_segment_to_split: Option<ast::PathSegment>, |
100 | // Wether to add 'self' in addition to the target path | 100 | // Wether to add 'self' in addition to the target path |
101 | add_self: bool, | 101 | add_self: bool, |
102 | }, | 102 | }, |
@@ -104,20 +104,20 @@ enum ImportAction<'a> { | |||
104 | AddInTreeList { | 104 | AddInTreeList { |
105 | common_segments: usize, | 105 | common_segments: usize, |
106 | // The UseTreeList where to add the target path | 106 | // The UseTreeList where to add the target path |
107 | tree_list: &'a ast::UseTreeList, | 107 | tree_list: ast::UseTreeList, |
108 | add_self: bool, | 108 | add_self: bool, |
109 | }, | 109 | }, |
110 | } | 110 | } |
111 | 111 | ||
112 | impl<'a> ImportAction<'a> { | 112 | impl ImportAction { |
113 | fn add_new_use(anchor: Option<&'a SyntaxNode>, add_after_anchor: bool) -> Self { | 113 | fn add_new_use(anchor: Option<SyntaxNode>, add_after_anchor: bool) -> Self { |
114 | ImportAction::AddNewUse { anchor, add_after_anchor } | 114 | ImportAction::AddNewUse { anchor, add_after_anchor } |
115 | } | 115 | } |
116 | 116 | ||
117 | fn add_nested_import( | 117 | fn add_nested_import( |
118 | common_segments: usize, | 118 | common_segments: usize, |
119 | path_to_split: &'a ast::Path, | 119 | path_to_split: ast::Path, |
120 | first_segment_to_split: Option<&'a ast::PathSegment>, | 120 | first_segment_to_split: Option<ast::PathSegment>, |
121 | add_self: bool, | 121 | add_self: bool, |
122 | ) -> Self { | 122 | ) -> Self { |
123 | ImportAction::AddNestedImport { | 123 | ImportAction::AddNestedImport { |
@@ -130,14 +130,14 @@ impl<'a> ImportAction<'a> { | |||
130 | 130 | ||
131 | fn add_in_tree_list( | 131 | fn add_in_tree_list( |
132 | common_segments: usize, | 132 | common_segments: usize, |
133 | tree_list: &'a ast::UseTreeList, | 133 | tree_list: ast::UseTreeList, |
134 | add_self: bool, | 134 | add_self: bool, |
135 | ) -> Self { | 135 | ) -> Self { |
136 | ImportAction::AddInTreeList { common_segments, tree_list, add_self } | 136 | ImportAction::AddInTreeList { common_segments, tree_list, add_self } |
137 | } | 137 | } |
138 | 138 | ||
139 | fn better<'b>(left: &'b ImportAction<'a>, right: &'b ImportAction<'a>) -> &'b ImportAction<'a> { | 139 | fn better(left: ImportAction, right: ImportAction) -> ImportAction { |
140 | if left.is_better(right) { | 140 | if left.is_better(&right) { |
141 | left | 141 | left |
142 | } else { | 142 | } else { |
143 | right | 143 | right |
@@ -166,12 +166,12 @@ impl<'a> ImportAction<'a> { | |||
166 | 166 | ||
167 | // Find out the best ImportAction to import target path against current_use_tree. | 167 | // Find out the best ImportAction to import target path against current_use_tree. |
168 | // If current_use_tree has a nested import the function gets called recursively on every UseTree inside a UseTreeList. | 168 | // If current_use_tree has a nested import the function gets called recursively on every UseTree inside a UseTreeList. |
169 | fn walk_use_tree_for_best_action<'a>( | 169 | fn walk_use_tree_for_best_action( |
170 | current_path_segments: &mut Vec<&'a ast::PathSegment>, // buffer containing path segments | 170 | current_path_segments: &mut Vec<ast::PathSegment>, // buffer containing path segments |
171 | current_parent_use_tree_list: Option<&'a ast::UseTreeList>, // will be Some value if we are in a nested import | 171 | current_parent_use_tree_list: Option<ast::UseTreeList>, // will be Some value if we are in a nested import |
172 | current_use_tree: &'a ast::UseTree, // the use tree we are currently examinating | 172 | current_use_tree: ast::UseTree, // the use tree we are currently examinating |
173 | target: &[SmolStr], // the path we want to import | 173 | target: &[SmolStr], // the path we want to import |
174 | ) -> ImportAction<'a> { | 174 | ) -> ImportAction { |
175 | // We save the number of segments in the buffer so we can restore the correct segments | 175 | // We save the number of segments in the buffer so we can restore the correct segments |
176 | // before returning. Recursive call will add segments so we need to delete them. | 176 | // before returning. Recursive call will add segments so we need to delete them. |
177 | let prev_len = current_path_segments.len(); | 177 | let prev_len = current_path_segments.len(); |
@@ -188,32 +188,36 @@ fn walk_use_tree_for_best_action<'a>( | |||
188 | .syntax() | 188 | .syntax() |
189 | .ancestors() | 189 | .ancestors() |
190 | .find_map(ast::UseItem::cast) | 190 | .find_map(ast::UseItem::cast) |
191 | .map(AstNode::syntax), | 191 | .map(|it| it.syntax().clone()), |
192 | true, | 192 | true, |
193 | ); | 193 | ); |
194 | } | 194 | } |
195 | }; | 195 | }; |
196 | 196 | ||
197 | // This can happen only if current_use_tree is a direct child of a UseItem | 197 | // This can happen only if current_use_tree is a direct child of a UseItem |
198 | if let Some(name) = alias.and_then(ast::NameOwner::name) { | 198 | if let Some(name) = alias.and_then(|it| it.name()) { |
199 | if compare_path_segment_with_name(&target[0], name) { | 199 | if compare_path_segment_with_name(&target[0], &name) { |
200 | return ImportAction::Nothing; | 200 | return ImportAction::Nothing; |
201 | } | 201 | } |
202 | } | 202 | } |
203 | 203 | ||
204 | collect_path_segments_raw(current_path_segments, path); | 204 | collect_path_segments_raw(current_path_segments, path.clone()); |
205 | 205 | ||
206 | // We compare only the new segments added in the line just above. | 206 | // We compare only the new segments added in the line just above. |
207 | // The first prev_len segments were already compared in 'parent' recursive calls. | 207 | // The first prev_len segments were already compared in 'parent' recursive calls. |
208 | let left = target.split_at(prev_len).1; | 208 | let left = target.split_at(prev_len).1; |
209 | let right = current_path_segments.split_at(prev_len).1; | 209 | let right = current_path_segments.split_at(prev_len).1; |
210 | let common = compare_path_segments(left, right); | 210 | let common = compare_path_segments(left, &right); |
211 | let mut action = match common { | 211 | let mut action = match common { |
212 | 0 => ImportAction::add_new_use( | 212 | 0 => ImportAction::add_new_use( |
213 | // e.g: target is std::fmt and we can have | 213 | // e.g: target is std::fmt and we can have |
214 | // use foo::bar | 214 | // use foo::bar |
215 | // We add a brand new use statement | 215 | // We add a brand new use statement |
216 | current_use_tree.syntax().ancestors().find_map(ast::UseItem::cast).map(AstNode::syntax), | 216 | current_use_tree |
217 | .syntax() | ||
218 | .ancestors() | ||
219 | .find_map(ast::UseItem::cast) | ||
220 | .map(|it| it.syntax().clone()), | ||
217 | true, | 221 | true, |
218 | ), | 222 | ), |
219 | common if common == left.len() && left.len() == right.len() => { | 223 | common if common == left.len() && left.len() == right.len() => { |
@@ -223,9 +227,9 @@ fn walk_use_tree_for_best_action<'a>( | |||
223 | if let Some(list) = tree_list { | 227 | if let Some(list) = tree_list { |
224 | // In case 2 we need to add self to the nested list | 228 | // In case 2 we need to add self to the nested list |
225 | // unless it's already there | 229 | // unless it's already there |
226 | let has_self = list.use_trees().map(ast::UseTree::path).any(|p| { | 230 | let has_self = list.use_trees().map(|it| it.path()).any(|p| { |
227 | p.and_then(ast::Path::segment) | 231 | p.and_then(|it| it.segment()) |
228 | .and_then(ast::PathSegment::kind) | 232 | .and_then(|it| it.kind()) |
229 | .filter(|k| *k == ast::PathSegmentKind::SelfKw) | 233 | .filter(|k| *k == ast::PathSegmentKind::SelfKw) |
230 | .is_some() | 234 | .is_some() |
231 | }); | 235 | }); |
@@ -248,7 +252,7 @@ fn walk_use_tree_for_best_action<'a>( | |||
248 | ImportAction::add_nested_import( | 252 | ImportAction::add_nested_import( |
249 | prev_len + common, | 253 | prev_len + common, |
250 | path, | 254 | path, |
251 | Some(segments_to_split[0]), | 255 | Some(segments_to_split[0].clone()), |
252 | false, | 256 | false, |
253 | ) | 257 | ) |
254 | } | 258 | } |
@@ -263,14 +267,18 @@ fn walk_use_tree_for_best_action<'a>( | |||
263 | .syntax() | 267 | .syntax() |
264 | .ancestors() | 268 | .ancestors() |
265 | .find_map(ast::UseItem::cast) | 269 | .find_map(ast::UseItem::cast) |
266 | .map(AstNode::syntax), | 270 | .map(|it| it.syntax().clone()), |
267 | true, | 271 | true, |
268 | ); | 272 | ); |
269 | if let Some(list) = tree_list { | 273 | if let Some(list) = tree_list { |
270 | // Case 2, check recursively if the path is already imported in the nested list | 274 | // Case 2, check recursively if the path is already imported in the nested list |
271 | for u in list.use_trees() { | 275 | for u in list.use_trees() { |
272 | let child_action = | 276 | let child_action = walk_use_tree_for_best_action( |
273 | walk_use_tree_for_best_action(current_path_segments, Some(list), u, target); | 277 | current_path_segments, |
278 | Some(list.clone()), | ||
279 | u, | ||
280 | target, | ||
281 | ); | ||
274 | if child_action.is_better(&better_action) { | 282 | if child_action.is_better(&better_action) { |
275 | better_action = child_action; | 283 | better_action = child_action; |
276 | if let ImportAction::Nothing = better_action { | 284 | if let ImportAction::Nothing = better_action { |
@@ -291,7 +299,7 @@ fn walk_use_tree_for_best_action<'a>( | |||
291 | ImportAction::add_nested_import( | 299 | ImportAction::add_nested_import( |
292 | prev_len + common, | 300 | prev_len + common, |
293 | path, | 301 | path, |
294 | Some(segments_to_split[0]), | 302 | Some(segments_to_split[0].clone()), |
295 | true, | 303 | true, |
296 | ) | 304 | ) |
297 | } | 305 | } |
@@ -302,7 +310,7 @@ fn walk_use_tree_for_best_action<'a>( | |||
302 | ImportAction::add_nested_import( | 310 | ImportAction::add_nested_import( |
303 | prev_len + common, | 311 | prev_len + common, |
304 | path, | 312 | path, |
305 | Some(segments_to_split[0]), | 313 | Some(segments_to_split[0].clone()), |
306 | false, | 314 | false, |
307 | ) | 315 | ) |
308 | } | 316 | } |
@@ -311,7 +319,7 @@ fn walk_use_tree_for_best_action<'a>( | |||
311 | 319 | ||
312 | // If we are inside a UseTreeList adding a use statement become adding to the existing | 320 | // If we are inside a UseTreeList adding a use statement become adding to the existing |
313 | // tree list. | 321 | // tree list. |
314 | action = match (current_parent_use_tree_list, action) { | 322 | action = match (current_parent_use_tree_list, action.clone()) { |
315 | (Some(use_tree_list), ImportAction::AddNewUse { .. }) => { | 323 | (Some(use_tree_list), ImportAction::AddNewUse { .. }) => { |
316 | ImportAction::add_in_tree_list(prev_len, use_tree_list, false) | 324 | ImportAction::add_in_tree_list(prev_len, use_tree_list, false) |
317 | } | 325 | } |
@@ -323,19 +331,20 @@ fn walk_use_tree_for_best_action<'a>( | |||
323 | action | 331 | action |
324 | } | 332 | } |
325 | 333 | ||
326 | fn best_action_for_target<'b, 'a: 'b>( | 334 | fn best_action_for_target( |
327 | container: &'a SyntaxNode, | 335 | container: SyntaxNode, |
328 | anchor: &'a SyntaxNode, | 336 | anchor: SyntaxNode, |
329 | target: &'b [SmolStr], | 337 | target: &[SmolStr], |
330 | ) -> ImportAction<'a> { | 338 | ) -> ImportAction { |
331 | let mut storage = Vec::with_capacity(16); // this should be the only allocation | 339 | let mut storage = Vec::with_capacity(16); // this should be the only allocation |
332 | let best_action = container | 340 | let best_action = container |
333 | .children() | 341 | .children() |
334 | .filter_map(ast::UseItem::cast) | 342 | .filter_map(ast::UseItem::cast) |
335 | .filter_map(ast::UseItem::use_tree) | 343 | .filter_map(|it| it.use_tree()) |
336 | .map(|u| walk_use_tree_for_best_action(&mut storage, None, u, target)) | 344 | .map(|u| walk_use_tree_for_best_action(&mut storage, None, u, target)) |
337 | .fold(None, |best, a| { | 345 | .fold(None, |best, a| match best { |
338 | best.and_then(|best| Some(*ImportAction::better(&best, &a))).or_else(|| Some(a)) | 346 | Some(best) => Some(ImportAction::better(best, a)), |
347 | None => Some(a), | ||
339 | }); | 348 | }); |
340 | 349 | ||
341 | match best_action { | 350 | match best_action { |
@@ -386,7 +395,7 @@ fn make_assist(action: &ImportAction, target: &[SmolStr], edit: &mut TextEditBui | |||
386 | } | 395 | } |
387 | 396 | ||
388 | fn make_assist_add_new_use( | 397 | fn make_assist_add_new_use( |
389 | anchor: &Option<&SyntaxNode>, | 398 | anchor: &Option<SyntaxNode>, |
390 | after: bool, | 399 | after: bool, |
391 | target: &[SmolStr], | 400 | target: &[SmolStr], |
392 | edit: &mut TextEditBuilder, | 401 | edit: &mut TextEditBuilder, |
@@ -396,7 +405,7 @@ fn make_assist_add_new_use( | |||
396 | let mut buf = String::new(); | 405 | let mut buf = String::new(); |
397 | if after { | 406 | if after { |
398 | buf.push_str("\n"); | 407 | buf.push_str("\n"); |
399 | if let Some(spaces) = indent { | 408 | if let Some(spaces) = &indent { |
400 | buf.push_str(spaces); | 409 | buf.push_str(spaces); |
401 | } | 410 | } |
402 | } | 411 | } |
@@ -405,8 +414,8 @@ fn make_assist_add_new_use( | |||
405 | buf.push_str(";"); | 414 | buf.push_str(";"); |
406 | if !after { | 415 | if !after { |
407 | buf.push_str("\n\n"); | 416 | buf.push_str("\n\n"); |
408 | if let Some(spaces) = indent { | 417 | if let Some(spaces) = &indent { |
409 | buf.push_str(spaces); | 418 | buf.push_str(&spaces); |
410 | } | 419 | } |
411 | } | 420 | } |
412 | let position = if after { anchor.range().end() } else { anchor.range().start() }; | 421 | let position = if after { anchor.range().end() } else { anchor.range().start() }; |
@@ -444,7 +453,7 @@ fn make_assist_add_in_tree_list( | |||
444 | 453 | ||
445 | fn make_assist_add_nested_import( | 454 | fn make_assist_add_nested_import( |
446 | path: &ast::Path, | 455 | path: &ast::Path, |
447 | first_segment_to_split: &Option<&ast::PathSegment>, | 456 | first_segment_to_split: &Option<ast::PathSegment>, |
448 | target: &[SmolStr], | 457 | target: &[SmolStr], |
449 | add_self: bool, | 458 | add_self: bool, |
450 | edit: &mut TextEditBuilder, | 459 | edit: &mut TextEditBuilder, |
@@ -482,7 +491,7 @@ fn apply_auto_import( | |||
482 | target: &[SmolStr], | 491 | target: &[SmolStr], |
483 | edit: &mut TextEditBuilder, | 492 | edit: &mut TextEditBuilder, |
484 | ) { | 493 | ) { |
485 | let action = best_action_for_target(container, path.syntax(), target); | 494 | let action = best_action_for_target(container.clone(), path.syntax().clone(), target); |
486 | make_assist(&action, target, edit); | 495 | make_assist(&action, target, edit); |
487 | if let Some(last) = path.segment() { | 496 | if let Some(last) = path.segment() { |
488 | // Here we are assuming the assist will provide a correct use statement | 497 | // Here we are assuming the assist will provide a correct use statement |
@@ -522,26 +531,26 @@ pub fn auto_import_text_edit( | |||
522 | edit: &mut TextEditBuilder, | 531 | edit: &mut TextEditBuilder, |
523 | ) { | 532 | ) { |
524 | let container = position.ancestors().find_map(|n| { | 533 | let container = position.ancestors().find_map(|n| { |
525 | if let Some(module) = ast::Module::cast(n) { | 534 | if let Some(module) = ast::Module::cast(n.clone()) { |
526 | return module.item_list().map(ast::AstNode::syntax); | 535 | return module.item_list().map(|it| it.syntax().clone()); |
527 | } | 536 | } |
528 | ast::SourceFile::cast(n).map(ast::AstNode::syntax) | 537 | ast::SourceFile::cast(n).map(|it| it.syntax().clone()) |
529 | }); | 538 | }); |
530 | 539 | ||
531 | if let Some(container) = container { | 540 | if let Some(container) = container { |
532 | let action = best_action_for_target(container, anchor, target); | 541 | let action = best_action_for_target(container, anchor.clone(), target); |
533 | make_assist(&action, target, edit); | 542 | make_assist(&action, target, edit); |
534 | } | 543 | } |
535 | } | 544 | } |
536 | 545 | ||
537 | pub(crate) fn auto_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 546 | pub(crate) fn auto_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
538 | let path: &ast::Path = ctx.node_at_offset()?; | 547 | let path: ast::Path = ctx.node_at_offset()?; |
539 | // We don't want to mess with use statements | 548 | // We don't want to mess with use statements |
540 | if path.syntax().ancestors().find_map(ast::UseItem::cast).is_some() { | 549 | if path.syntax().ancestors().find_map(ast::UseItem::cast).is_some() { |
541 | return None; | 550 | return None; |
542 | } | 551 | } |
543 | 552 | ||
544 | let hir_path = hir::Path::from_ast(path)?; | 553 | let hir_path = hir::Path::from_ast(path.clone())?; |
545 | let segments = collect_hir_path_segments(&hir_path); | 554 | let segments = collect_hir_path_segments(&hir_path); |
546 | if segments.len() < 2 { | 555 | if segments.len() < 2 { |
547 | return None; | 556 | return None; |
@@ -554,7 +563,7 @@ pub(crate) fn auto_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist | |||
554 | format!("import {} in mod {}", fmt_segments(&segments), name.text()), | 563 | format!("import {} in mod {}", fmt_segments(&segments), name.text()), |
555 | |edit| { | 564 | |edit| { |
556 | let mut text_edit = TextEditBuilder::default(); | 565 | let mut text_edit = TextEditBuilder::default(); |
557 | apply_auto_import(item_list.syntax(), path, &segments, &mut text_edit); | 566 | apply_auto_import(item_list.syntax(), &path, &segments, &mut text_edit); |
558 | edit.set_edit_builder(text_edit); | 567 | edit.set_edit_builder(text_edit); |
559 | }, | 568 | }, |
560 | ); | 569 | ); |
@@ -566,7 +575,7 @@ pub(crate) fn auto_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist | |||
566 | format!("import {} in the current file", fmt_segments(&segments)), | 575 | format!("import {} in the current file", fmt_segments(&segments)), |
567 | |edit| { | 576 | |edit| { |
568 | let mut text_edit = TextEditBuilder::default(); | 577 | let mut text_edit = TextEditBuilder::default(); |
569 | apply_auto_import(current_file.syntax(), path, &segments, &mut text_edit); | 578 | apply_auto_import(current_file.syntax(), &path, &segments, &mut text_edit); |
570 | edit.set_edit_builder(text_edit); | 579 | edit.set_edit_builder(text_edit); |
571 | }, | 580 | }, |
572 | ); | 581 | ); |