@@ -75,73 +75,82 @@ fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option
75
75
76
76
let in_item_list = matches ! ( kind, Some ( ItemListKind :: SourceFile | ItemListKind :: Module ) | None ) ;
77
77
let in_assoc_non_trait_impl = matches ! ( kind, Some ( ItemListKind :: Impl | ItemListKind :: Trait ) ) ;
78
+
78
79
let in_extern_block = matches ! ( kind, Some ( ItemListKind :: ExternBlock ) ) ;
79
80
let in_trait = matches ! ( kind, Some ( ItemListKind :: Trait ) ) ;
80
81
let in_trait_impl = matches ! ( kind, Some ( ItemListKind :: TraitImpl ( _) ) ) ;
81
82
let in_inherent_impl = matches ! ( kind, Some ( ItemListKind :: Impl ) ) ;
82
- let no_vis_qualifiers = ctx. qualifier_ctx . vis_node . is_none ( ) ;
83
83
let in_block = kind. is_none ( ) ;
84
84
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 ( ) ;
97
88
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
+ }
101
93
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
+ }
108
102
109
- return ;
103
+ if in_item_list || in_assoc_non_trait_impl {
104
+ add_keyword ( "fn" , "fn $1($2) {\n $0\n }" ) ;
110
105
}
111
106
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 {
117
108
add_keyword ( "trait" , "trait $1 {\n $0\n }" ) ;
118
- add_keyword ( "union" , "union $1 {\n $0\n }" ) ;
119
- add_keyword ( "use" , "use $0" ) ;
120
109
if no_vis_qualifiers {
121
110
add_keyword ( "impl" , "impl $1 {\n $0\n }" ) ;
122
111
}
123
112
}
124
113
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 }" ) ;
129
137
}
138
+ }
130
139
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" ) ;
139
147
}
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" ) ;
145
149
}
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" ) ;
146
155
}
147
156
}
0 commit comments