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

Commit c5dcc77

Browse files
committed
Fix visibility mods not being completed for field defs
1 parent 519ac81 commit c5dcc77

File tree

10 files changed

+85
-15
lines changed

10 files changed

+85
-15
lines changed

crates/ide-completion/src/completions.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pub(crate) mod attribute;
44
pub(crate) mod dot;
55
pub(crate) mod expr;
66
pub(crate) mod extern_abi;
7+
pub(crate) mod field;
78
pub(crate) mod flyimport;
89
pub(crate) mod fn_param;
910
pub(crate) mod format_string;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//! Completion of field list position.
2+
3+
use crate::{
4+
context::{IdentContext, NameContext, NameKind, NameRefContext, PathCompletionCtx, PathKind},
5+
CompletionContext, CompletionItem, CompletionItemKind, Completions,
6+
};
7+
8+
pub(crate) fn complete_field_list(acc: &mut Completions, ctx: &CompletionContext) {
9+
match &ctx.ident_ctx {
10+
IdentContext::Name(NameContext { kind: NameKind::RecordField, .. })
11+
| IdentContext::NameRef(NameRefContext {
12+
path_ctx:
13+
Some(PathCompletionCtx {
14+
has_macro_bang: false,
15+
is_absolute_path: false,
16+
qualifier: None,
17+
parent: None,
18+
kind: PathKind::Type { in_tuple_struct: true },
19+
has_type_args: false,
20+
..
21+
}),
22+
..
23+
}) => {
24+
if ctx.qualifier_ctx.vis_node.is_none() {
25+
let mut add_keyword = |kw, snippet| add_keyword(acc, ctx, kw, snippet);
26+
add_keyword("pub(crate)", "pub(crate)");
27+
add_keyword("pub(super)", "pub(super)");
28+
add_keyword("pub", "pub");
29+
}
30+
}
31+
_ => return,
32+
}
33+
}
34+
35+
pub(super) fn add_keyword(acc: &mut Completions, ctx: &CompletionContext, kw: &str, snippet: &str) {
36+
let mut item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), kw);
37+
38+
match ctx.config.snippet_cap {
39+
Some(cap) => {
40+
if snippet.ends_with('}') && ctx.incomplete_let {
41+
// complete block expression snippets with a trailing semicolon, if inside an incomplete let
42+
cov_mark::hit!(let_semi);
43+
item.insert_snippet(cap, format!("{};", snippet));
44+
} else {
45+
item.insert_snippet(cap, snippet);
46+
}
47+
}
48+
None => {
49+
item.insert_text(if snippet.contains('$') { kw } else { snippet });
50+
}
51+
};
52+
item.add_to(acc);
53+
}

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,10 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
160160
(_, ItemInNs::Types(hir::ModuleDef::Module(_))) => true,
161161
// and so are macros(except for attributes)
162162
(
163-
PathKind::Expr { .. } | PathKind::Type | PathKind::Item { .. } | PathKind::Pat,
163+
PathKind::Expr { .. }
164+
| PathKind::Type { .. }
165+
| PathKind::Item { .. }
166+
| PathKind::Pat,
164167
ItemInNs::Macros(mac),
165168
) => mac.is_fn_like(ctx.db),
166169
(PathKind::Item { .. }, _) => true,
@@ -170,14 +173,14 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
170173
(PathKind::Pat, ItemInNs::Types(_)) => true,
171174
(PathKind::Pat, ItemInNs::Values(def)) => matches!(def, hir::ModuleDef::Const(_)),
172175

173-
(PathKind::Type, ItemInNs::Types(ty)) => {
176+
(PathKind::Type { .. }, ItemInNs::Types(ty)) => {
174177
if matches!(ctx.completion_location, Some(ImmediateLocation::TypeBound)) {
175178
matches!(ty, ModuleDef::Trait(_))
176179
} else {
177180
true
178181
}
179182
}
180-
(PathKind::Type, ItemInNs::Values(_)) => false,
183+
(PathKind::Type { .. }, ItemInNs::Values(_)) => false,
181184

182185
(PathKind::Attr { .. }, ItemInNs::Macros(mac)) => mac.is_attr(ctx.db),
183186
(PathKind::Attr { .. }, _) => false,

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@ pub(crate) fn complete_type_path(acc: &mut Completions, ctx: &CompletionContext)
1818
}
1919

2020
let (&is_absolute_path, qualifier) = match ctx.path_context() {
21-
Some(PathCompletionCtx { kind: PathKind::Type, is_absolute_path, qualifier, .. }) => {
22-
(is_absolute_path, qualifier)
23-
}
21+
Some(PathCompletionCtx {
22+
kind: PathKind::Type { .. },
23+
is_absolute_path,
24+
qualifier,
25+
..
26+
}) => (is_absolute_path, qualifier),
2427
_ => return,
2528
};
2629

crates/ide-completion/src/context.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ pub(super) enum PathKind {
4949
in_block_expr: bool,
5050
in_loop_body: bool,
5151
},
52-
Type,
52+
Type {
53+
in_tuple_struct: bool,
54+
},
5355
Attr {
5456
kind: AttrKind,
5557
annotated_item_kind: Option<SyntaxKind>,
@@ -1222,7 +1224,9 @@ impl<'a> CompletionContext<'a> {
12221224
// using Option<Option<PathKind>> as extra controlflow
12231225
let kind = match_ast! {
12241226
match it {
1225-
ast::PathType(_) => Some(PathKind::Type),
1227+
ast::PathType(it) => Some(PathKind::Type {
1228+
in_tuple_struct: it.syntax().parent().map_or(false, |it| ast::TupleField::can_cast(it.kind()))
1229+
}),
12261230
ast::PathExpr(it) => {
12271231
if let Some(p) = it.syntax().parent() {
12281232
if ast::ExprStmt::can_cast(p.kind()) {
@@ -1262,7 +1266,7 @@ impl<'a> CompletionContext<'a> {
12621266
let parent = it.syntax().parent();
12631267
match parent.as_ref().map(|it| it.kind()) {
12641268
Some(SyntaxKind::MACRO_PAT) => Some(PathKind::Pat),
1265-
Some(SyntaxKind::MACRO_TYPE) => Some(PathKind::Type),
1269+
Some(SyntaxKind::MACRO_TYPE) => Some(PathKind::Type { in_tuple_struct: false }),
12661270
Some(SyntaxKind::ITEM_LIST) => Some(PathKind::Item { kind: ItemListKind::Module }),
12671271
Some(SyntaxKind::ASSOC_ITEM_LIST) => Some(PathKind::Item { kind: match parent.and_then(|it| it.parent()) {
12681272
Some(it) => match_ast! {

crates/ide-completion/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ pub fn completions(
158158
completions::dot::complete_dot(acc, ctx);
159159
completions::expr::complete_expr_path(acc, ctx);
160160
completions::extern_abi::complete_extern_abi(acc, ctx);
161+
completions::field::complete_field_list(acc, ctx);
161162
completions::flyimport::import_on_the_fly(acc, ctx);
162163
completions::fn_param::complete_fn_param(acc, ctx);
163164
completions::format_string::format_string(acc, ctx);

crates/ide-completion/src/render.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ fn render_resolution_simple_(
286286
// Add `<>` for generic types
287287
let type_path_no_ty_args = matches!(
288288
ctx.completion.path_context(),
289-
Some(PathCompletionCtx { kind: PathKind::Type, has_type_args: false, .. })
289+
Some(PathCompletionCtx { kind: PathKind::Type { .. }, has_type_args: false, .. })
290290
) && ctx.completion.config.callable.is_some();
291291
if type_path_no_ty_args {
292292
if let Some(cap) = ctx.snippet_cap() {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ fn should_add_parens(ctx: &CompletionContext) -> bool {
202202
Some(PathCompletionCtx { kind: PathKind::Expr { .. }, has_call_parens: true, .. }) => {
203203
return false
204204
}
205-
Some(PathCompletionCtx { kind: PathKind::Use | PathKind::Type, .. }) => {
205+
Some(PathCompletionCtx { kind: PathKind::Use | PathKind::Type { .. }, .. }) => {
206206
cov_mark::hit!(no_parens_in_use_item);
207207
return false;
208208
}

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,17 @@ fn after_fn_name() {
100100

101101
#[test]
102102
fn before_record_field() {
103-
// FIXME: This should emit visibility qualifiers
104103
check(
105104
r#"
106105
struct Foo {
107106
$0
108107
pub f: i32,
109108
}
110109
"#,
111-
expect![[r#""#]],
110+
expect![[r#"
111+
kw pub
112+
kw pub(crate)
113+
kw pub(super)
114+
"#]],
112115
)
113116
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,13 @@ struct Foo<'lt, T, const C: usize> {
3838

3939
#[test]
4040
fn tuple_struct_field() {
41-
// FIXME: This should emit visibility qualifiers
4241
check(
4342
r#"
4443
struct Foo<'lt, T, const C: usize>(f$0);
4544
"#,
4645
expect![[r#"
4746
en Enum
48-
ma makro!(…) macro_rules! makro
47+
ma makro!(…) macro_rules! makro
4948
md module
5049
sp Self
5150
st Foo<…>
@@ -57,6 +56,9 @@ struct Foo<'lt, T, const C: usize>(f$0);
5756
un Union
5857
bt u32
5958
kw crate::
59+
kw pub
60+
kw pub(crate)
61+
kw pub(super)
6062
kw self::
6163
kw super::
6264
"#]],

0 commit comments

Comments
 (0)