Skip to content

Commit 6effb26

Browse files
committed
Auto merge of #14095 - dqkqd:master, r=Veykril
Add postfix completion for `unsafe`. Fix #13779. Hi, this is my first PR. Please tell me if there is anything I should do.
2 parents a05ce5a + 2666e6e commit 6effb26

File tree

4 files changed

+156
-84
lines changed

4 files changed

+156
-84
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ fn foo(a: A) { a.$0 }
8686
sn match match expr {}
8787
sn ref &expr
8888
sn refm &mut expr
89+
sn unsafe unsafe {}
8990
"#]],
9091
);
9192

@@ -110,6 +111,7 @@ fn foo() {
110111
sn match match expr {}
111112
sn ref &expr
112113
sn refm &mut expr
114+
sn unsafe unsafe {}
113115
"#]],
114116
);
115117
}
@@ -136,6 +138,7 @@ fn foo(a: A) { a.$0 }
136138
sn match match expr {}
137139
sn ref &expr
138140
sn refm &mut expr
141+
sn unsafe unsafe {}
139142
"#]],
140143
);
141144
}

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

Lines changed: 107 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use hir::{Documentation, HasAttrs};
66
use ide_db::{imports::insert_use::ImportScope, ty_filter::TryEnum, SnippetCap};
77
use syntax::{
88
ast::{self, make, AstNode, AstToken},
9-
SyntaxKind::{EXPR_STMT, STMT_LIST},
9+
SyntaxKind::{BLOCK_EXPR, EXPR_STMT, FOR_EXPR, IF_EXPR, LOOP_EXPR, STMT_LIST, WHILE_EXPR},
1010
TextRange, TextSize,
1111
};
1212
use text_edit::TextEdit;
@@ -123,6 +123,22 @@ pub(crate) fn complete_postfix(
123123
postfix_snippet("ref", "&expr", &format!("&{receiver_text}")).add_to(acc);
124124
postfix_snippet("refm", "&mut expr", &format!("&mut {receiver_text}")).add_to(acc);
125125

126+
let mut unsafe_should_be_wrapped = true;
127+
if dot_receiver.syntax().kind() == BLOCK_EXPR {
128+
unsafe_should_be_wrapped = false;
129+
if let Some(parent) = dot_receiver.syntax().parent() {
130+
if matches!(parent.kind(), IF_EXPR | WHILE_EXPR | LOOP_EXPR | FOR_EXPR) {
131+
unsafe_should_be_wrapped = true;
132+
}
133+
}
134+
};
135+
let unsafe_completion_string = if unsafe_should_be_wrapped {
136+
format!("unsafe {{ {receiver_text} }}")
137+
} else {
138+
format!("unsafe {receiver_text}")
139+
};
140+
postfix_snippet("unsafe", "unsafe {}", &unsafe_completion_string).add_to(acc);
141+
126142
// The rest of the postfix completions create an expression that moves an argument,
127143
// so it's better to consider references now to avoid breaking the compilation
128144

@@ -329,18 +345,19 @@ fn main() {
329345
}
330346
"#,
331347
expect![[r#"
332-
sn box Box::new(expr)
333-
sn call function(expr)
334-
sn dbg dbg!(expr)
335-
sn dbgr dbg!(&expr)
336-
sn if if expr {}
337-
sn let let
338-
sn letm let mut
339-
sn match match expr {}
340-
sn not !expr
341-
sn ref &expr
342-
sn refm &mut expr
343-
sn while while expr {}
348+
sn box Box::new(expr)
349+
sn call function(expr)
350+
sn dbg dbg!(expr)
351+
sn dbgr dbg!(&expr)
352+
sn if if expr {}
353+
sn let let
354+
sn letm let mut
355+
sn match match expr {}
356+
sn not !expr
357+
sn ref &expr
358+
sn refm &mut expr
359+
sn unsafe unsafe {}
360+
sn while while expr {}
344361
"#]],
345362
);
346363
}
@@ -359,16 +376,17 @@ fn main() {
359376
}
360377
"#,
361378
expect![[r#"
362-
sn box Box::new(expr)
363-
sn call function(expr)
364-
sn dbg dbg!(expr)
365-
sn dbgr dbg!(&expr)
366-
sn if if expr {}
367-
sn match match expr {}
368-
sn not !expr
369-
sn ref &expr
370-
sn refm &mut expr
371-
sn while while expr {}
379+
sn box Box::new(expr)
380+
sn call function(expr)
381+
sn dbg dbg!(expr)
382+
sn dbgr dbg!(&expr)
383+
sn if if expr {}
384+
sn match match expr {}
385+
sn not !expr
386+
sn ref &expr
387+
sn refm &mut expr
388+
sn unsafe unsafe {}
389+
sn while while expr {}
372390
"#]],
373391
);
374392
}
@@ -383,15 +401,16 @@ fn main() {
383401
}
384402
"#,
385403
expect![[r#"
386-
sn box Box::new(expr)
387-
sn call function(expr)
388-
sn dbg dbg!(expr)
389-
sn dbgr dbg!(&expr)
390-
sn let let
391-
sn letm let mut
392-
sn match match expr {}
393-
sn ref &expr
394-
sn refm &mut expr
404+
sn box Box::new(expr)
405+
sn call function(expr)
406+
sn dbg dbg!(expr)
407+
sn dbgr dbg!(&expr)
408+
sn let let
409+
sn letm let mut
410+
sn match match expr {}
411+
sn ref &expr
412+
sn refm &mut expr
413+
sn unsafe unsafe {}
395414
"#]],
396415
)
397416
}
@@ -406,18 +425,19 @@ fn main() {
406425
}
407426
"#,
408427
expect![[r#"
409-
sn box Box::new(expr)
410-
sn call function(expr)
411-
sn dbg dbg!(expr)
412-
sn dbgr dbg!(&expr)
413-
sn if if expr {}
414-
sn let let
415-
sn letm let mut
416-
sn match match expr {}
417-
sn not !expr
418-
sn ref &expr
419-
sn refm &mut expr
420-
sn while while expr {}
428+
sn box Box::new(expr)
429+
sn call function(expr)
430+
sn dbg dbg!(expr)
431+
sn dbgr dbg!(&expr)
432+
sn if if expr {}
433+
sn let let
434+
sn letm let mut
435+
sn match match expr {}
436+
sn not !expr
437+
sn ref &expr
438+
sn refm &mut expr
439+
sn unsafe unsafe {}
440+
sn while while expr {}
421441
"#]],
422442
);
423443
}
@@ -517,6 +537,49 @@ fn main() {
517537
)
518538
}
519539

540+
#[test]
541+
fn postfix_completion_for_unsafe() {
542+
check_edit("unsafe", r#"fn main() { foo.$0 }"#, r#"fn main() { unsafe { foo } }"#);
543+
check_edit("unsafe", r#"fn main() { { foo }.$0 }"#, r#"fn main() { unsafe { foo } }"#);
544+
check_edit(
545+
"unsafe",
546+
r#"fn main() { if x { foo }.$0 }"#,
547+
r#"fn main() { unsafe { if x { foo } } }"#,
548+
);
549+
check_edit(
550+
"unsafe",
551+
r#"fn main() { loop { foo }.$0 }"#,
552+
r#"fn main() { unsafe { loop { foo } } }"#,
553+
);
554+
check_edit(
555+
"unsafe",
556+
r#"fn main() { if true {}.$0 }"#,
557+
r#"fn main() { unsafe { if true {} } }"#,
558+
);
559+
check_edit(
560+
"unsafe",
561+
r#"fn main() { while true {}.$0 }"#,
562+
r#"fn main() { unsafe { while true {} } }"#,
563+
);
564+
check_edit(
565+
"unsafe",
566+
r#"fn main() { for i in 0..10 {}.$0 }"#,
567+
r#"fn main() { unsafe { for i in 0..10 {} } }"#,
568+
);
569+
check_edit(
570+
"unsafe",
571+
r#"fn main() { let x = if true {1} else {2}.$0 }"#,
572+
r#"fn main() { let x = unsafe { if true {1} else {2} } }"#,
573+
);
574+
575+
// completion will not be triggered
576+
check_edit(
577+
"unsafe",
578+
r#"fn main() { let x = true else {panic!()}.$0}"#,
579+
r#"fn main() { let x = true else {panic!()}.unsafe}"#,
580+
);
581+
}
582+
520583
#[test]
521584
fn custom_postfix_completion() {
522585
let config = CompletionConfig {

crates/ide-completion/src/render.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,6 +1691,7 @@ fn main() {
16911691
sn while []
16921692
sn ref []
16931693
sn refm []
1694+
sn unsafe []
16941695
sn match []
16951696
sn box []
16961697
sn dbg []
@@ -1718,6 +1719,7 @@ fn main() {
17181719
me f() []
17191720
sn ref []
17201721
sn refm []
1722+
sn unsafe []
17211723
sn match []
17221724
sn box []
17231725
sn dbg []

crates/ide-completion/src/tests/proc_macros.rs

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,17 @@ fn main() {
2424
}
2525
"#,
2626
expect![[r#"
27-
me foo() fn(&self)
28-
sn box Box::new(expr)
29-
sn call function(expr)
30-
sn dbg dbg!(expr)
31-
sn dbgr dbg!(&expr)
32-
sn let let
33-
sn letm let mut
34-
sn match match expr {}
35-
sn ref &expr
36-
sn refm &mut expr
27+
me foo() fn(&self)
28+
sn box Box::new(expr)
29+
sn call function(expr)
30+
sn dbg dbg!(expr)
31+
sn dbgr dbg!(&expr)
32+
sn let let
33+
sn letm let mut
34+
sn match match expr {}
35+
sn ref &expr
36+
sn refm &mut expr
37+
sn unsafe unsafe {}
3738
"#]],
3839
)
3940
}
@@ -54,16 +55,17 @@ fn main() {
5455
}
5556
"#,
5657
expect![[r#"
57-
me foo() fn(&self)
58-
sn box Box::new(expr)
59-
sn call function(expr)
60-
sn dbg dbg!(expr)
61-
sn dbgr dbg!(&expr)
62-
sn let let
63-
sn letm let mut
64-
sn match match expr {}
65-
sn ref &expr
66-
sn refm &mut expr
58+
me foo() fn(&self)
59+
sn box Box::new(expr)
60+
sn call function(expr)
61+
sn dbg dbg!(expr)
62+
sn dbgr dbg!(&expr)
63+
sn let let
64+
sn letm let mut
65+
sn match match expr {}
66+
sn ref &expr
67+
sn refm &mut expr
68+
sn unsafe unsafe {}
6769
"#]],
6870
)
6971
}
@@ -86,16 +88,17 @@ impl Foo {
8688
fn main() {}
8789
"#,
8890
expect![[r#"
89-
me foo() fn(&self)
90-
sn box Box::new(expr)
91-
sn call function(expr)
92-
sn dbg dbg!(expr)
93-
sn dbgr dbg!(&expr)
94-
sn let let
95-
sn letm let mut
96-
sn match match expr {}
97-
sn ref &expr
98-
sn refm &mut expr
91+
me foo() fn(&self)
92+
sn box Box::new(expr)
93+
sn call function(expr)
94+
sn dbg dbg!(expr)
95+
sn dbgr dbg!(&expr)
96+
sn let let
97+
sn letm let mut
98+
sn match match expr {}
99+
sn ref &expr
100+
sn refm &mut expr
101+
sn unsafe unsafe {}
99102
"#]],
100103
)
101104
}
@@ -118,16 +121,17 @@ impl Foo {
118121
fn main() {}
119122
"#,
120123
expect![[r#"
121-
me foo() fn(&self)
122-
sn box Box::new(expr)
123-
sn call function(expr)
124-
sn dbg dbg!(expr)
125-
sn dbgr dbg!(&expr)
126-
sn let let
127-
sn letm let mut
128-
sn match match expr {}
129-
sn ref &expr
130-
sn refm &mut expr
124+
me foo() fn(&self)
125+
sn box Box::new(expr)
126+
sn call function(expr)
127+
sn dbg dbg!(expr)
128+
sn dbgr dbg!(&expr)
129+
sn let let
130+
sn letm let mut
131+
sn match match expr {}
132+
sn ref &expr
133+
sn refm &mut expr
134+
sn unsafe unsafe {}
131135
"#]],
132136
)
133137
}

0 commit comments

Comments
 (0)