Skip to content

Commit 7a4994d

Browse files
committed
Auto merge of rust-lang#12361 - Veykril:completion, r=Veykril
internal: Simplify DotAccess representation in completions `@bors` r+
2 parents d5965aa + 697ade6 commit 7a4994d

File tree

4 files changed

+57
-53
lines changed

4 files changed

+57
-53
lines changed

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

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,31 @@
33
use ide_db::FxHashSet;
44

55
use crate::{
6-
context::{CompletionContext, DotAccess, NameRefContext, PathCompletionCtx, PathKind},
7-
Completions,
6+
context::{
7+
CompletionContext, DotAccess, DotAccessKind, NameRefContext, PathCompletionCtx, PathKind,
8+
},
9+
CompletionItem, CompletionItemKind, Completions,
810
};
911

1012
/// Complete dot accesses, i.e. fields or methods.
1113
pub(crate) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
12-
let (dot_access, dot_receiver) = match ctx.nameref_ctx() {
14+
let (dot_access, receiver_ty) = match ctx.nameref_ctx() {
1315
Some(NameRefContext {
14-
dot_access:
15-
Some(
16-
access @ (DotAccess::Method { receiver: Some(receiver), .. }
17-
| DotAccess::Field { receiver: Some(receiver), .. }),
18-
),
16+
dot_access: Some(access @ DotAccess { receiver_ty: Some(receiver_ty), .. }),
1917
..
20-
}) => (access, receiver),
18+
}) => (access, &receiver_ty.original),
2119
_ => return complete_undotted_self(acc, ctx),
2220
};
2321

24-
let receiver_ty = match ctx.sema.type_of_expr(dot_receiver) {
25-
Some(ty) => ty.original,
26-
_ => return,
27-
};
22+
// Suggest .await syntax for types that implement Future trait
23+
if receiver_ty.impls_future(ctx.db) {
24+
let mut item =
25+
CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), "await");
26+
item.detail("expr.await");
27+
item.add_to(acc);
28+
}
2829

29-
if let DotAccess::Method { .. } = dot_access {
30+
if let DotAccessKind::Method { .. } = dot_access.kind {
3031
cov_mark::hit!(test_no_struct_field_completion_for_method_call);
3132
} else {
3233
complete_fields(

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

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use text_edit::TextEdit;
1313

1414
use crate::{
1515
completions::postfix::format_like::add_format_like_completions,
16-
context::{CompletionContext, DotAccess, NameRefContext},
16+
context::{CompletionContext, DotAccess, DotAccessKind, NameRefContext},
1717
item::{Builder, CompletionRelevancePostfixMatch},
1818
CompletionItem, CompletionItemKind, CompletionRelevance, Completions, SnippetScope,
1919
};
@@ -23,34 +23,25 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
2323
return;
2424
}
2525

26-
let (dot_receiver, receiver_is_ambiguous_float_literal) = match ctx.nameref_ctx() {
26+
let (dot_receiver, receiver_ty, receiver_is_ambiguous_float_literal) = match ctx.nameref_ctx() {
2727
Some(NameRefContext {
28-
dot_access: Some(DotAccess::Method { receiver: Some(it), .. }),
28+
dot_access: Some(DotAccess { receiver_ty: Some(ty), receiver: Some(it), kind, .. }),
2929
..
30-
}) => (it, false),
31-
Some(NameRefContext {
32-
dot_access:
33-
Some(DotAccess::Field { receiver: Some(it), receiver_is_ambiguous_float_literal }),
34-
..
35-
}) => (it, *receiver_is_ambiguous_float_literal),
30+
}) => (
31+
it,
32+
&ty.original,
33+
match *kind {
34+
DotAccessKind::Field { receiver_is_ambiguous_float_literal } => {
35+
receiver_is_ambiguous_float_literal
36+
}
37+
DotAccessKind::Method { .. } => false,
38+
},
39+
),
3640
_ => return,
3741
};
3842

3943
let receiver_text = get_receiver_text(dot_receiver, receiver_is_ambiguous_float_literal);
4044

41-
let receiver_ty = match ctx.sema.type_of_expr(dot_receiver) {
42-
Some(it) => it.original,
43-
None => return,
44-
};
45-
46-
// Suggest .await syntax for types that implement Future trait
47-
if receiver_ty.impls_future(ctx.db) {
48-
let mut item =
49-
CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), "await");
50-
item.detail("expr.await");
51-
item.add_to(acc);
52-
}
53-
5445
let cap = match ctx.config.snippet_cap {
5546
Some(it) => it,
5647
None => return,

crates/ide-completion/src/context.rs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -186,15 +186,20 @@ pub(super) enum IdentContext {
186186
}
187187

188188
#[derive(Debug)]
189-
pub(super) enum DotAccess {
189+
pub(super) struct DotAccess {
190+
pub(super) receiver: Option<ast::Expr>,
191+
pub(super) receiver_ty: Option<TypeInfo>,
192+
pub(super) kind: DotAccessKind,
193+
}
194+
195+
#[derive(Debug)]
196+
pub(super) enum DotAccessKind {
190197
Field {
191-
receiver: Option<ast::Expr>,
192198
/// True if the receiver is an integer and there is no ident in the original file after it yet
193199
/// like `0.$0`
194200
receiver_is_ambiguous_float_literal: bool,
195201
},
196202
Method {
197-
receiver: Option<ast::Expr>,
198203
has_parens: bool,
199204
},
200205
}
@@ -298,11 +303,9 @@ impl<'a> CompletionContext<'a> {
298303

299304
pub(crate) fn dot_receiver(&self) -> Option<&ast::Expr> {
300305
match self.nameref_ctx() {
301-
Some(NameRefContext {
302-
dot_access:
303-
Some(DotAccess::Method { receiver, .. } | DotAccess::Field { receiver, .. }),
304-
..
305-
}) => receiver.as_ref(),
306+
Some(NameRefContext { dot_access: Some(DotAccess { receiver, .. }), .. }) => {
307+
receiver.as_ref()
308+
}
306309
_ => None,
307310
}
308311
}
@@ -1073,16 +1076,20 @@ impl<'a> CompletionContext<'a> {
10731076
},
10741077
_ => false,
10751078
};
1076-
nameref_ctx.dot_access = Some(DotAccess::Field { receiver, receiver_is_ambiguous_float_literal });
1079+
nameref_ctx.dot_access = Some(DotAccess {
1080+
receiver_ty: receiver.as_ref().and_then(|it| sema.type_of_expr(it)),
1081+
kind: DotAccessKind::Field { receiver_is_ambiguous_float_literal },
1082+
receiver
1083+
});
10771084
return (nameref_ctx, None);
10781085
},
10791086
ast::MethodCallExpr(method) => {
1080-
nameref_ctx.dot_access = Some(
1081-
DotAccess::Method {
1082-
receiver: find_in_original_file(method.receiver(), original_file),
1083-
has_parens: method.arg_list().map_or(false, |it| it.l_paren_token().is_some())
1084-
}
1085-
);
1087+
let receiver = find_in_original_file(method.receiver(), original_file);
1088+
nameref_ctx.dot_access = Some(DotAccess {
1089+
receiver_ty: receiver.as_ref().and_then(|it| sema.type_of_expr(it)),
1090+
kind: DotAccessKind::Method { has_parens: method.arg_list().map_or(false, |it| it.l_paren_token().is_some()) },
1091+
receiver
1092+
});
10861093
return (nameref_ctx, None);
10871094
},
10881095
_ => return (nameref_ctx, None),

crates/ide-completion/src/render/function.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ use stdx::{format_to, to_lower_snake_case};
77
use syntax::SmolStr;
88

99
use crate::{
10-
context::{CompletionContext, DotAccess, NameRefContext, PathCompletionCtx, PathKind},
10+
context::{
11+
CompletionContext, DotAccess, DotAccessKind, NameRefContext, PathCompletionCtx, PathKind,
12+
},
1113
item::{Builder, CompletionItem, CompletionItemKind, CompletionRelevance},
1214
render::{compute_exact_name_match, compute_ref_match, compute_type_match, RenderContext},
1315
CallableSnippets,
@@ -209,7 +211,10 @@ fn should_add_parens(ctx: &CompletionContext) -> bool {
209211

210212
if matches!(
211213
ctx.nameref_ctx(),
212-
Some(NameRefContext { dot_access: Some(DotAccess::Method { has_parens: true, .. }), .. })
214+
Some(NameRefContext {
215+
dot_access: Some(DotAccess { kind: DotAccessKind::Method { has_parens: true }, .. }),
216+
..
217+
})
213218
) {
214219
return false;
215220
}

0 commit comments

Comments
 (0)