@@ -76,7 +76,10 @@ fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option
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 ) ) ;
7878
79- let in_extern_block = matches ! ( kind, Some ( ItemListKind :: ExternBlock ) ) ;
79+ let in_extern_block = matches ! ( kind, Some ( ItemListKind :: ExternBlock { .. } ) ) ;
80+ let in_unsafe_extern_block =
81+ matches ! ( kind, Some ( ItemListKind :: ExternBlock { is_unsafe: true } ) ) ;
82+
8083 let in_trait = matches ! ( kind, Some ( ItemListKind :: Trait ) ) ;
8184 let in_trait_impl = matches ! ( kind, Some ( ItemListKind :: TraitImpl ( _) ) ) ;
8285 let in_inherent_impl = matches ! ( kind, Some ( ItemListKind :: Impl ) ) ;
@@ -85,29 +88,39 @@ fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option
8588 let no_vis_qualifiers = ctx. qualifier_ctx . vis_node . is_none ( ) ;
8689 let has_unsafe_kw = ctx. qualifier_ctx . unsafe_tok . is_some ( ) ;
8790 let has_async_kw = ctx. qualifier_ctx . async_tok . is_some ( ) ;
91+ let has_safe_kw = ctx. qualifier_ctx . safe_tok . is_some ( ) ;
8892
8993 // We handle completions for trait-impls in [`item_list::trait_impl`]
9094 if in_trait_impl {
9195 return ;
9296 }
9397
9498 // 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- }
99+ if has_unsafe_kw || has_async_kw || has_safe_kw {
100+ if in_extern_block {
101+ add_keyword ( "fn" , "fn $1($2);" ) ;
102+ add_keyword ( "static" , "static $1: $2;" ) ;
103+ } else {
104+ if !has_unsafe_kw {
105+ add_keyword ( "unsafe" , "unsafe $0" ) ;
106+ }
107+ if !has_async_kw {
108+ add_keyword ( "async" , "async $0" ) ;
109+ }
102110
103- if in_item_list || in_assoc_non_trait_impl {
104- add_keyword ( "fn" , "fn $1($2) {\n $0\n }" ) ;
105- }
111+ if in_item_list || in_assoc_non_trait_impl {
112+ add_keyword ( "fn" , "fn $1($2) {\n $0\n }" ) ;
113+ }
106114
107- if has_unsafe_kw && in_item_list {
108- add_keyword ( "trait" , "trait $1 {\n $0\n }" ) ;
109- if no_vis_qualifiers {
110- add_keyword ( "impl" , "impl $1 {\n $0\n }" ) ;
115+ if has_unsafe_kw && in_item_list {
116+ add_keyword ( "trait" , "trait $1 {\n $0\n }" ) ;
117+ if no_vis_qualifiers {
118+ add_keyword ( "impl" , "impl $1 {\n $0\n }" ) ;
119+ }
120+ }
121+
122+ if !has_async_kw && no_vis_qualifiers && in_item_list {
123+ add_keyword ( "extern" , "extern $0" ) ;
111124 }
112125 }
113126
@@ -138,6 +151,11 @@ fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option
138151 }
139152
140153 if in_extern_block {
154+ add_keyword ( "unsafe" , "unsafe $0" ) ;
155+ if in_unsafe_extern_block {
156+ add_keyword ( "safe" , "safe $0" ) ;
157+ }
158+
141159 add_keyword ( "fn" , "fn $1($2);" ) ;
142160 add_keyword ( "static" , "static $1: $2;" ) ;
143161 } else {
0 commit comments