Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 161ab76

Browse files
committed
Auto merge of rust-lang#12376 - Veykril:completion, r=Veykril
fix: Insert whitespace into trait-impl completions when coming from macros Fixes rust-lang/rust-analyzer#12278
2 parents 4ca47b3 + 86d1d90 commit 161ab76

File tree

8 files changed

+100
-92
lines changed

8 files changed

+100
-92
lines changed

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,6 @@ struct Foo(usize);
939939
940940
impl FooB for Foo {
941941
$0fn foo< 'lt>(& 'lt self){}
942-
943942
}
944943
"#,
945944
)

crates/ide-completion/src/completions/flyimport.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
114114
|| ctx.is_path_disallowed()
115115
|| ctx.expects_item()
116116
|| ctx.expects_assoc_item()
117-
|| ctx.expects_variant()
118117
{
119118
return None;
120119
}

crates/ide-completion/src/completions/trait_impl.rs

Lines changed: 91 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,12 @@
3232
//! ```
3333
3434
use hir::{self, HasAttrs};
35-
use ide_db::{path_transform::PathTransform, traits::get_missing_assoc_items, SymbolKind};
35+
use ide_db::{
36+
path_transform::PathTransform, syntax_helpers::insert_whitespace_into_node,
37+
traits::get_missing_assoc_items, SymbolKind,
38+
};
3639
use syntax::{
3740
ast::{self, edit_in_place::AttrsOwnerEdit},
38-
display::function_declaration,
3941
AstNode, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, T,
4042
};
4143
use text_edit::TextEdit;
@@ -179,7 +181,7 @@ fn add_function_impl(
179181
_ => unreachable!(),
180182
};
181183

182-
let function_decl = function_declaration(&transformed_fn);
184+
let function_decl = function_declaration(&transformed_fn, source.file_id.is_macro());
183185
match ctx.config.snippet_cap {
184186
Some(cap) => {
185187
let snippet = format!("{} {{\n $0\n}}", function_decl);
@@ -260,7 +262,7 @@ fn add_const_impl(
260262
_ => unreachable!(),
261263
};
262264

263-
let label = make_const_compl_syntax(&transformed_const);
265+
let label = make_const_compl_syntax(&transformed_const, source.file_id.is_macro());
264266
let replacement = format!("{} ", label);
265267

266268
let mut item = CompletionItem::new(SymbolKind::Const, replacement_range, label);
@@ -283,29 +285,55 @@ fn add_const_impl(
283285
}
284286
}
285287

286-
fn make_const_compl_syntax(const_: &ast::Const) -> String {
288+
fn make_const_compl_syntax(const_: &ast::Const, needs_whitespace: bool) -> String {
287289
const_.remove_attrs_and_docs();
290+
let const_ = if needs_whitespace {
291+
insert_whitespace_into_node::insert_ws_into(const_.syntax().clone())
292+
} else {
293+
const_.syntax().clone()
294+
};
288295

289-
let const_start = const_.syntax().text_range().start();
290-
let const_end = const_.syntax().text_range().end();
291-
292-
let start =
293-
const_.syntax().first_child_or_token().map_or(const_start, |f| f.text_range().start());
296+
let start = const_.text_range().start();
297+
let const_end = const_.text_range().end();
294298

295299
let end = const_
296-
.syntax()
297300
.children_with_tokens()
298301
.find(|s| s.kind() == T![;] || s.kind() == T![=])
299302
.map_or(const_end, |f| f.text_range().start());
300303

301304
let len = end - start;
302305
let range = TextRange::new(0.into(), len);
303306

304-
let syntax = const_.syntax().text().slice(range).to_string();
307+
let syntax = const_.text().slice(range).to_string();
305308

306309
format!("{} =", syntax.trim_end())
307310
}
308311

312+
fn function_declaration(node: &ast::Fn, needs_whitespace: bool) -> String {
313+
node.remove_attrs_and_docs();
314+
315+
let node = if needs_whitespace {
316+
insert_whitespace_into_node::insert_ws_into(node.syntax().clone())
317+
} else {
318+
node.syntax().clone()
319+
};
320+
321+
let start = node.text_range().start();
322+
let end = node.text_range().end();
323+
324+
let end = node
325+
.last_child_or_token()
326+
.filter(|s| s.kind() == T![;] || s.kind() == SyntaxKind::BLOCK_EXPR)
327+
.map_or(end, |f| f.text_range().start());
328+
329+
let len = end - start;
330+
let range = TextRange::new(0.into(), len);
331+
332+
let syntax = node.text().slice(range).to_string();
333+
334+
syntax.trim_end().to_owned()
335+
}
336+
309337
fn replacement_range(ctx: &CompletionContext, item: &SyntaxNode) -> TextRange {
310338
let first_child = item
311339
.children_with_tokens()
@@ -655,8 +683,7 @@ trait Test {
655683
struct T;
656684
657685
impl Test for T {
658-
fn foo<T>()
659-
where T: Into<String> {
686+
fn foo<T>() where T: Into<String> {
660687
$0
661688
}
662689
}
@@ -992,7 +1019,7 @@ trait SomeTrait<T> {}
9921019
9931020
trait Foo<T> {
9941021
fn function()
995-
where Self: SomeTrait<T>;
1022+
where Self: SomeTrait<T>;
9961023
}
9971024
struct Bar;
9981025
@@ -1005,13 +1032,13 @@ trait SomeTrait<T> {}
10051032
10061033
trait Foo<T> {
10071034
fn function()
1008-
where Self: SomeTrait<T>;
1035+
where Self: SomeTrait<T>;
10091036
}
10101037
struct Bar;
10111038
10121039
impl Foo<u32> for Bar {
10131040
fn function()
1014-
where Self: SomeTrait<u32> {
1041+
where Self: SomeTrait<u32> {
10151042
$0
10161043
}
10171044
}
@@ -1052,4 +1079,51 @@ impl Tr for () {
10521079
"#]],
10531080
);
10541081
}
1082+
1083+
#[test]
1084+
fn fixes_up_macro_generated() {
1085+
check_edit(
1086+
"fn foo",
1087+
r#"
1088+
macro_rules! noop {
1089+
($($item: item)*) => {
1090+
$($item)*
1091+
}
1092+
}
1093+
1094+
noop! {
1095+
trait Foo {
1096+
fn foo(&mut self, bar: i64, baz: &mut u32) -> Result<(), u32>;
1097+
}
1098+
}
1099+
1100+
struct Test;
1101+
1102+
impl Foo for Test {
1103+
$0
1104+
}
1105+
"#,
1106+
r#"
1107+
macro_rules! noop {
1108+
($($item: item)*) => {
1109+
$($item)*
1110+
}
1111+
}
1112+
1113+
noop! {
1114+
trait Foo {
1115+
fn foo(&mut self, bar: i64, baz: &mut u32) -> Result<(), u32>;
1116+
}
1117+
}
1118+
1119+
struct Test;
1120+
1121+
impl Foo for Test {
1122+
fn foo(&mut self,bar:i64,baz: &mut u32) -> Result<(),u32> {
1123+
$0
1124+
}
1125+
}
1126+
"#,
1127+
);
1128+
}
10551129
}

crates/ide-completion/src/context.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -322,10 +322,6 @@ impl<'a> CompletionContext<'a> {
322322
matches!(self.completion_location, Some(ImmediateLocation::Trait | ImmediateLocation::Impl))
323323
}
324324

325-
pub(crate) fn expects_variant(&self) -> bool {
326-
matches!(self.name_ctx(), Some(NameContext { kind: NameKind::Variant, .. }))
327-
}
328-
329325
pub(crate) fn expects_non_trait_assoc_item(&self) -> bool {
330326
matches!(self.completion_location, Some(ImmediateLocation::Impl))
331327
}
@@ -379,10 +375,7 @@ impl<'a> CompletionContext<'a> {
379375
pub(crate) fn is_path_disallowed(&self) -> bool {
380376
self.previous_token_is(T![unsafe])
381377
|| matches!(self.prev_sibling, Some(ImmediatePrevSibling::Visibility))
382-
|| matches!(
383-
self.name_ctx(),
384-
Some(NameContext { kind: NameKind::Module(_) | NameKind::Rename, .. })
385-
)
378+
|| (matches!(self.name_ctx(), Some(NameContext { .. })) && self.pattern_ctx.is_none())
386379
|| matches!(self.pattern_ctx, Some(PatternContext { record_pat: Some(_), .. }))
387380
|| matches!(
388381
self.nameref_ctx(),

crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ pub fn insert_ws_into(syn: SyntaxNode) -> SyntaxNode {
114114
ted::insert(pos, insert);
115115
}
116116

117+
if let Some(it) = syn.last_token().filter(|it| it.kind() == SyntaxKind::WHITESPACE) {
118+
ted::remove(it);
119+
}
120+
117121
syn
118122
}
119123

crates/ide/src/expand_macro.rs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,7 @@ fn main() {
250250
"#,
251251
expect![[r#"
252252
bar
253-
for _ in 0..42{}
254-
"#]],
253+
for _ in 0..42{}"#]],
255254
);
256255
}
257256

@@ -273,7 +272,6 @@ f$0oo!();
273272
expect![[r#"
274273
foo
275274
fn b(){}
276-
277275
"#]],
278276
);
279277
}
@@ -297,8 +295,7 @@ f$0oo!();
297295
fn some_thing() -> u32 {
298296
let a = 0;
299297
a+10
300-
}
301-
"#]],
298+
}"#]],
302299
);
303300
}
304301

@@ -359,8 +356,7 @@ fn main() {
359356
"#,
360357
expect![[r#"
361358
match_ast
362-
{}
363-
"#]],
359+
{}"#]],
364360
);
365361
}
366362

@@ -421,8 +417,7 @@ fn main() {
421417
"#,
422418
expect![[r#"
423419
foo
424-
fn f<T>(_: &dyn ::std::marker::Copy){}
425-
"#]],
420+
fn f<T>(_: &dyn ::std::marker::Copy){}"#]],
426421
);
427422
}
428423

@@ -440,7 +435,6 @@ struct Foo {}
440435
expect![[r#"
441436
Clone
442437
impl < >core::clone::Clone for Foo< >{}
443-
444438
"#]],
445439
);
446440
}
@@ -458,7 +452,6 @@ struct Foo {}
458452
expect![[r#"
459453
Copy
460454
impl < >core::marker::Copy for Foo< >{}
461-
462455
"#]],
463456
);
464457
}
@@ -475,7 +468,6 @@ struct Foo {}
475468
expect![[r#"
476469
Copy
477470
impl < >core::marker::Copy for Foo< >{}
478-
479471
"#]],
480472
);
481473
check(
@@ -488,7 +480,6 @@ struct Foo {}
488480
expect![[r#"
489481
Clone
490482
impl < >core::clone::Clone for Foo< >{}
491-
492483
"#]],
493484
);
494485
}

crates/syntax/src/display.rs

Lines changed: 0 additions & 51 deletions
This file was deleted.

crates/syntax/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ mod token_text;
3333
#[cfg(test)]
3434
mod tests;
3535

36-
pub mod display;
3736
pub mod algo;
3837
pub mod ast;
3938
#[doc(hidden)]

0 commit comments

Comments
 (0)