@@ -75,73 +75,82 @@ fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option
7575
7676 let in_item_list = matches ! ( kind, Some ( ItemListKind :: SourceFile | ItemListKind :: Module ) | None ) ;
7777 let in_assoc_non_trait_impl = matches ! ( kind, Some ( ItemListKind :: Impl | ItemListKind :: Trait ) ) ;
78+
7879 let in_extern_block = matches ! ( kind, Some ( ItemListKind :: ExternBlock ) ) ;
7980 let in_trait = matches ! ( kind, Some ( ItemListKind :: Trait ) ) ;
8081 let in_trait_impl = matches ! ( kind, Some ( ItemListKind :: TraitImpl ( _) ) ) ;
8182 let in_inherent_impl = matches ! ( kind, Some ( ItemListKind :: Impl ) ) ;
82- let no_vis_qualifiers = ctx. qualifier_ctx . vis_node . is_none ( ) ;
8383 let in_block = kind. is_none ( ) ;
8484
85- let missing_qualifiers = [
86- ctx. qualifier_ctx . unsafe_tok . is_none ( ) . then_some ( ( "unsafe" , "unsafe $0" ) ) ,
87- ctx. qualifier_ctx . async_tok . is_none ( ) . then_some ( ( "async" , "async $0" ) ) ,
88- ] ;
89-
90- if !in_trait_impl {
91- // handle qualifier tokens
92- if missing_qualifiers. iter ( ) . any ( Option :: is_none) {
93- // only complete missing qualifiers
94- missing_qualifiers. iter ( ) . filter_map ( |x| * x) . for_each ( |( kw, snippet) | {
95- add_keyword ( kw, snippet) ;
96- } ) ;
85+ let no_vis_qualifiers = ctx. qualifier_ctx . vis_node . is_none ( ) ;
86+ let has_unsafe_kw = ctx. qualifier_ctx . unsafe_tok . is_some ( ) ;
87+ let has_async_kw = ctx. qualifier_ctx . async_tok . is_some ( ) ;
9788
98- if in_item_list || in_assoc_non_trait_impl {
99- add_keyword ( "fn" , "fn $1($2) {\n $0\n }" ) ;
100- }
89+ // We handle completions for trait-impls in [`item_list::trait_impl`]
90+ if in_trait_impl {
91+ return ;
92+ }
10193
102- if ctx. qualifier_ctx . unsafe_tok . is_some ( ) && in_item_list {
103- add_keyword ( "trait" , "trait $1 {\n $0\n }" ) ;
104- if no_vis_qualifiers {
105- add_keyword ( "impl" , "impl $1 {\n $0\n }" ) ;
106- }
107- }
94+ // Some keywords are invalid after non-vis qualifiers, so we handle them first.
95+ if has_unsafe_kw || has_async_kw {
96+ if !has_unsafe_kw {
97+ add_keyword ( "unsafe" , "unsafe $0" ) ;
98+ }
99+ if !has_async_kw {
100+ add_keyword ( "async" , "async $0" ) ;
101+ }
108102
109- return ;
103+ if in_item_list || in_assoc_non_trait_impl {
104+ add_keyword ( "fn" , "fn $1($2) {\n $0\n }" ) ;
110105 }
111106
112- if in_item_list {
113- add_keyword ( "enum" , "enum $1 {\n $0\n }" ) ;
114- add_keyword ( "mod" , "mod $0" ) ;
115- add_keyword ( "static" , "static $0" ) ;
116- add_keyword ( "struct" , "struct $0" ) ;
107+ if has_unsafe_kw && in_item_list {
117108 add_keyword ( "trait" , "trait $1 {\n $0\n }" ) ;
118- add_keyword ( "union" , "union $1 {\n $0\n }" ) ;
119- add_keyword ( "use" , "use $0" ) ;
120109 if no_vis_qualifiers {
121110 add_keyword ( "impl" , "impl $1 {\n $0\n }" ) ;
122111 }
123112 }
124113
125- if !in_trait && !in_block && no_vis_qualifiers {
126- add_keyword ( "pub(crate)" , "pub(crate) $0" ) ;
127- add_keyword ( "pub(super)" , "pub(super) $0" ) ;
128- add_keyword ( "pub" , "pub $0" ) ;
114+ return ;
115+ }
116+
117+ // ...and the rest deals with cases without any non-vis qualifiers.
118+
119+ // Visibility qualifiers
120+ if !in_trait && !in_block && no_vis_qualifiers {
121+ add_keyword ( "pub(crate)" , "pub(crate) $0" ) ;
122+ add_keyword ( "pub(super)" , "pub(super) $0" ) ;
123+ add_keyword ( "pub" , "pub $0" ) ;
124+ }
125+
126+ // Keywords that are valid in `item_list`
127+ if in_item_list {
128+ add_keyword ( "enum" , "enum $1 {\n $0\n }" ) ;
129+ add_keyword ( "mod" , "mod $0" ) ;
130+ add_keyword ( "static" , "static $0" ) ;
131+ add_keyword ( "struct" , "struct $0" ) ;
132+ add_keyword ( "trait" , "trait $1 {\n $0\n }" ) ;
133+ add_keyword ( "union" , "union $1 {\n $0\n }" ) ;
134+ add_keyword ( "use" , "use $0" ) ;
135+ if no_vis_qualifiers {
136+ add_keyword ( "impl" , "impl $1 {\n $0\n }" ) ;
129137 }
138+ }
130139
131- if in_extern_block {
132- add_keyword ( "fn" , "fn $1($2);" ) ;
133- } else {
134- if !in_inherent_impl {
135- if !in_trait {
136- add_keyword ( "extern" , "extern $0" ) ;
137- }
138- add_keyword ( "type" , "type $0" ) ;
140+ if in_extern_block {
141+ add_keyword ( "fn" , "fn $1($2);" ) ;
142+ add_keyword ( "static" , "static $1: $2;" ) ;
143+ } else {
144+ if !in_inherent_impl {
145+ if !in_trait {
146+ add_keyword ( "extern" , "extern $0" ) ;
139147 }
140-
141- add_keyword ( "fn" , "fn $1($2) {\n $0\n }" ) ;
142- add_keyword ( "unsafe" , "unsafe $0" ) ;
143- add_keyword ( "const" , "const $0" ) ;
144- add_keyword ( "async" , "async $0" ) ;
148+ add_keyword ( "type" , "type $0" ) ;
145149 }
150+
151+ add_keyword ( "fn" , "fn $1($2) {\n $0\n }" ) ;
152+ add_keyword ( "unsafe" , "unsafe $0" ) ;
153+ add_keyword ( "const" , "const $0" ) ;
154+ add_keyword ( "async" , "async $0" ) ;
146155 }
147156}
0 commit comments