Skip to content

Commit 82674e2

Browse files
committed
Auto merge of rust-lang#16454 - Veykril:break-return-postfix, r=Veykril
feat: Add break and return postfix keyword completions
2 parents ddf2611 + ddddc9c commit 82674e2

File tree

16 files changed

+262
-122
lines changed

16 files changed

+262
-122
lines changed

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

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ use ide_db::FxHashSet;
44
use syntax::SmolStr;
55

66
use crate::{
7-
context::{CompletionContext, DotAccess, DotAccessKind, ExprCtx, PathCompletionCtx, Qualified},
7+
context::{
8+
CompletionContext, DotAccess, DotAccessExprCtx, DotAccessKind, PathCompletionCtx,
9+
PathExprCtx, Qualified,
10+
},
811
CompletionItem, CompletionItemKind, Completions,
912
};
1013

@@ -51,7 +54,7 @@ pub(crate) fn complete_undotted_self(
5154
acc: &mut Completions,
5255
ctx: &CompletionContext<'_>,
5356
path_ctx: &PathCompletionCtx,
54-
expr_ctx: &ExprCtx,
57+
expr_ctx: &PathExprCtx,
5558
) {
5659
if !ctx.config.enable_self_on_the_fly {
5760
return;
@@ -66,7 +69,7 @@ pub(crate) fn complete_undotted_self(
6669
return;
6770
}
6871
let self_param = match expr_ctx {
69-
ExprCtx { self_param: Some(self_param), .. } => self_param,
72+
PathExprCtx { self_param: Some(self_param), .. } => self_param,
7073
_ => return,
7174
};
7275

@@ -82,6 +85,10 @@ pub(crate) fn complete_undotted_self(
8285
receiver: None,
8386
receiver_ty: None,
8487
kind: DotAccessKind::Field { receiver_is_ambiguous_float_literal: false },
88+
ctx: DotAccessExprCtx {
89+
in_block_expr: expr_ctx.in_block_expr,
90+
in_breakable: expr_ctx.in_breakable,
91+
},
8592
},
8693
Some(hir::known::SELF_PARAM),
8794
field,
@@ -99,6 +106,10 @@ pub(crate) fn complete_undotted_self(
99106
receiver: None,
100107
receiver_ty: None,
101108
kind: DotAccessKind::Method { has_parens: false },
109+
ctx: DotAccessExprCtx {
110+
in_block_expr: expr_ctx.in_block_expr,
111+
in_breakable: expr_ctx.in_breakable,
112+
},
102113
},
103114
func,
104115
Some(hir::known::SELF_PARAM),

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,24 @@ use syntax::ast;
55

66
use crate::{
77
completions::record::add_default_update,
8-
context::{ExprCtx, PathCompletionCtx, Qualified},
8+
context::{BreakableKind, PathCompletionCtx, PathExprCtx, Qualified},
99
CompletionContext, Completions,
1010
};
1111

1212
pub(crate) fn complete_expr_path(
1313
acc: &mut Completions,
1414
ctx: &CompletionContext<'_>,
1515
path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx,
16-
expr_ctx: &ExprCtx,
16+
expr_ctx: &PathExprCtx,
1717
) {
1818
let _p = tracing::span!(tracing::Level::INFO, "complete_expr_path").entered();
1919
if !ctx.qualifier_ctx.none() {
2020
return;
2121
}
2222

23-
let &ExprCtx {
23+
let &PathExprCtx {
2424
in_block_expr,
25-
in_loop_body,
25+
in_breakable,
2626
after_if_expr,
2727
in_condition,
2828
incomplete_let,
@@ -290,7 +290,7 @@ pub(crate) fn complete_expr_path(
290290
add_keyword("mut", "mut ");
291291
}
292292

293-
if in_loop_body {
293+
if in_breakable != BreakableKind::None {
294294
if in_block_expr {
295295
add_keyword("continue", "continue;");
296296
add_keyword("break", "break;");

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Completion of paths and keywords at item list position.
22
33
use crate::{
4-
context::{ExprCtx, ItemListKind, PathCompletionCtx, Qualified},
4+
context::{ItemListKind, PathCompletionCtx, PathExprCtx, Qualified},
55
CompletionContext, Completions,
66
};
77

@@ -11,7 +11,7 @@ pub(crate) fn complete_item_list_in_expr(
1111
acc: &mut Completions,
1212
ctx: &CompletionContext<'_>,
1313
path_ctx: &PathCompletionCtx,
14-
expr_ctx: &ExprCtx,
14+
expr_ctx: &PathExprCtx,
1515
) {
1616
if !expr_ctx.in_block_expr {
1717
return;

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,13 @@ fn foo(a: A) { a.$0 }
8181
sn call function(expr)
8282
sn dbg dbg!(expr)
8383
sn dbgr dbg!(&expr)
84+
sn deref *expr
8485
sn let let
8586
sn letm let mut
8687
sn match match expr {}
8788
sn ref &expr
8889
sn refm &mut expr
90+
sn return return expr
8991
sn unsafe unsafe {}
9092
"#]],
9193
);
@@ -106,11 +108,13 @@ fn foo() {
106108
sn call function(expr)
107109
sn dbg dbg!(expr)
108110
sn dbgr dbg!(&expr)
111+
sn deref *expr
109112
sn let let
110113
sn letm let mut
111114
sn match match expr {}
112115
sn ref &expr
113116
sn refm &mut expr
117+
sn return return expr
114118
sn unsafe unsafe {}
115119
"#]],
116120
);
@@ -133,11 +137,13 @@ fn foo(a: A) { a.$0 }
133137
sn call function(expr)
134138
sn dbg dbg!(expr)
135139
sn dbgr dbg!(&expr)
140+
sn deref *expr
136141
sn let let
137142
sn letm let mut
138143
sn match match expr {}
139144
sn ref &expr
140145
sn refm &mut expr
146+
sn return return expr
141147
sn unsafe unsafe {}
142148
"#]],
143149
);

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

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
mod format_like;
44

5+
use hir::ItemInNs;
56
use ide_db::{
67
documentation::{Documentation, HasDocs},
78
imports::insert_use::ImportScope,
@@ -17,7 +18,7 @@ use text_edit::TextEdit;
1718

1819
use crate::{
1920
completions::postfix::format_like::add_format_like_completions,
20-
context::{CompletionContext, DotAccess, DotAccessKind},
21+
context::{BreakableKind, CompletionContext, DotAccess, DotAccessKind},
2122
item::{Builder, CompletionRelevancePostfixMatch},
2223
CompletionItem, CompletionItemKind, CompletionRelevance, Completions, SnippetScope,
2324
};
@@ -44,6 +45,7 @@ pub(crate) fn complete_postfix(
4445
),
4546
_ => return,
4647
};
48+
let expr_ctx = &dot_access.ctx;
4749

4850
let receiver_text = get_receiver_text(dot_receiver, receiver_is_ambiguous_float_literal);
4951

@@ -59,16 +61,22 @@ pub(crate) fn complete_postfix(
5961

6062
if let Some(drop_trait) = ctx.famous_defs().core_ops_Drop() {
6163
if receiver_ty.impls_trait(ctx.db, drop_trait, &[]) {
62-
if let &[hir::AssocItem::Function(drop_fn)] = &*drop_trait.items(ctx.db) {
63-
cov_mark::hit!(postfix_drop_completion);
64-
// FIXME: check that `drop` is in scope, use fully qualified path if it isn't/if shadowed
65-
let mut item = postfix_snippet(
66-
"drop",
67-
"fn drop(&mut self)",
68-
&format!("drop($0{receiver_text})"),
69-
);
70-
item.set_documentation(drop_fn.docs(ctx.db));
71-
item.add_to(acc, ctx.db);
64+
if let Some(drop_fn) = ctx.famous_defs().core_mem_drop() {
65+
if let Some(path) = ctx.module.find_use_path(
66+
ctx.db,
67+
ItemInNs::Values(drop_fn.into()),
68+
ctx.config.prefer_no_std,
69+
ctx.config.prefer_prelude,
70+
) {
71+
cov_mark::hit!(postfix_drop_completion);
72+
let mut item = postfix_snippet(
73+
"drop",
74+
"fn drop(&mut self)",
75+
&format!("{path}($0{receiver_text})", path = path.display(ctx.db)),
76+
);
77+
item.set_documentation(drop_fn.docs(ctx.db));
78+
item.add_to(acc, ctx.db);
79+
}
7280
}
7381
}
7482
}
@@ -140,6 +148,7 @@ pub(crate) fn complete_postfix(
140148

141149
postfix_snippet("ref", "&expr", &format!("&{receiver_text}")).add_to(acc, ctx.db);
142150
postfix_snippet("refm", "&mut expr", &format!("&mut {receiver_text}")).add_to(acc, ctx.db);
151+
postfix_snippet("deref", "*expr", &format!("*{receiver_text}")).add_to(acc, ctx.db);
143152

144153
let mut unsafe_should_be_wrapped = true;
145154
if dot_receiver.syntax().kind() == BLOCK_EXPR {
@@ -224,6 +233,28 @@ pub(crate) fn complete_postfix(
224233
add_format_like_completions(acc, ctx, &dot_receiver, cap, &literal_text);
225234
}
226235
}
236+
237+
postfix_snippet(
238+
"return",
239+
"return expr",
240+
&format!(
241+
"return {receiver_text}{semi}",
242+
semi = if expr_ctx.in_block_expr { ";" } else { "" }
243+
),
244+
)
245+
.add_to(acc, ctx.db);
246+
247+
if let BreakableKind::Block | BreakableKind::Loop = expr_ctx.in_breakable {
248+
postfix_snippet(
249+
"break",
250+
"break expr",
251+
&format!(
252+
"break {receiver_text}{semi}",
253+
semi = if expr_ctx.in_block_expr { ";" } else { "" }
254+
),
255+
)
256+
.add_to(acc, ctx.db);
257+
}
227258
}
228259

229260
fn get_receiver_text(receiver: &ast::Expr, receiver_is_ambiguous_float_literal: bool) -> String {
@@ -368,13 +399,15 @@ fn main() {
368399
sn call function(expr)
369400
sn dbg dbg!(expr)
370401
sn dbgr dbg!(&expr)
402+
sn deref *expr
371403
sn if if expr {}
372404
sn let let
373405
sn letm let mut
374406
sn match match expr {}
375407
sn not !expr
376408
sn ref &expr
377409
sn refm &mut expr
410+
sn return return expr
378411
sn unsafe unsafe {}
379412
sn while while expr {}
380413
"#]],
@@ -399,11 +432,13 @@ fn main() {
399432
sn call function(expr)
400433
sn dbg dbg!(expr)
401434
sn dbgr dbg!(&expr)
435+
sn deref *expr
402436
sn if if expr {}
403437
sn match match expr {}
404438
sn not !expr
405439
sn ref &expr
406440
sn refm &mut expr
441+
sn return return expr
407442
sn unsafe unsafe {}
408443
sn while while expr {}
409444
"#]],
@@ -424,11 +459,13 @@ fn main() {
424459
sn call function(expr)
425460
sn dbg dbg!(expr)
426461
sn dbgr dbg!(&expr)
462+
sn deref *expr
427463
sn let let
428464
sn letm let mut
429465
sn match match expr {}
430466
sn ref &expr
431467
sn refm &mut expr
468+
sn return return expr
432469
sn unsafe unsafe {}
433470
"#]],
434471
)
@@ -448,13 +485,15 @@ fn main() {
448485
sn call function(expr)
449486
sn dbg dbg!(expr)
450487
sn dbgr dbg!(&expr)
488+
sn deref *expr
451489
sn if if expr {}
452490
sn let let
453491
sn letm let mut
454492
sn match match expr {}
455493
sn not !expr
456494
sn ref &expr
457495
sn refm &mut expr
496+
sn return return expr
458497
sn unsafe unsafe {}
459498
sn while while expr {}
460499
"#]],

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use syntax::{
66
};
77

88
use crate::{
9-
context::{DotAccess, DotAccessKind, PatternContext},
9+
context::{DotAccess, DotAccessExprCtx, DotAccessKind, PatternContext},
1010
CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance,
1111
CompletionRelevancePostfixMatch, Completions,
1212
};
@@ -118,12 +118,17 @@ fn complete_fields(
118118
missing_fields: Vec<(hir::Field, hir::Type)>,
119119
) {
120120
for (field, ty) in missing_fields {
121+
// This should call something else, we shouldn't be synthesizing a DotAccess here
121122
acc.add_field(
122123
ctx,
123124
&DotAccess {
124125
receiver: None,
125126
receiver_ty: None,
126127
kind: DotAccessKind::Field { receiver_is_ambiguous_float_literal: false },
128+
ctx: DotAccessExprCtx {
129+
in_block_expr: false,
130+
in_breakable: crate::context::BreakableKind::None,
131+
},
127132
},
128133
None,
129134
field,

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use ide_db::{documentation::Documentation, imports::insert_use::ImportScope, SnippetCap};
44

55
use crate::{
6-
context::{ExprCtx, ItemListKind, PathCompletionCtx, Qualified},
6+
context::{ItemListKind, PathCompletionCtx, PathExprCtx, Qualified},
77
item::Builder,
88
CompletionContext, CompletionItem, CompletionItemKind, Completions, SnippetScope,
99
};
@@ -12,7 +12,7 @@ pub(crate) fn complete_expr_snippet(
1212
acc: &mut Completions,
1313
ctx: &CompletionContext<'_>,
1414
path_ctx: &PathCompletionCtx,
15-
&ExprCtx { in_block_expr, .. }: &ExprCtx,
15+
&PathExprCtx { in_block_expr, .. }: &PathExprCtx,
1616
) {
1717
if !matches!(path_ctx.qualified, Qualified::No) {
1818
return;

0 commit comments

Comments
 (0)