@@ -76,7 +76,10 @@ fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option
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
+ 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
+
80
83
let in_trait = matches ! ( kind, Some ( ItemListKind :: Trait ) ) ;
81
84
let in_trait_impl = matches ! ( kind, Some ( ItemListKind :: TraitImpl ( _) ) ) ;
82
85
let in_inherent_impl = matches ! ( kind, Some ( ItemListKind :: Impl ) ) ;
@@ -85,29 +88,39 @@ fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option
85
88
let no_vis_qualifiers = ctx. qualifier_ctx . vis_node . is_none ( ) ;
86
89
let has_unsafe_kw = ctx. qualifier_ctx . unsafe_tok . is_some ( ) ;
87
90
let has_async_kw = ctx. qualifier_ctx . async_tok . is_some ( ) ;
91
+ let has_safe_kw = ctx. qualifier_ctx . safe_tok . is_some ( ) ;
88
92
89
93
// We handle completions for trait-impls in [`item_list::trait_impl`]
90
94
if in_trait_impl {
91
95
return ;
92
96
}
93
97
94
98
// 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
+ }
102
110
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
+ }
106
114
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" ) ;
111
124
}
112
125
}
113
126
@@ -138,6 +151,11 @@ fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option
138
151
}
139
152
140
153
if in_extern_block {
154
+ add_keyword ( "unsafe" , "unsafe $0" ) ;
155
+ if in_unsafe_extern_block {
156
+ add_keyword ( "safe" , "safe $0" ) ;
157
+ }
158
+
141
159
add_keyword ( "fn" , "fn $1($2);" ) ;
142
160
add_keyword ( "static" , "static $1: $2;" ) ;
143
161
} else {
0 commit comments