@@ -5,7 +5,7 @@ use syntax::{
55 SyntaxKind :: WHITESPACE ,
66 T ,
77 ast:: { self , AstNode , HasName , make} ,
8- ted,
8+ ted:: { self , Position } ,
99} ;
1010
1111use crate :: {
@@ -131,7 +131,7 @@ fn add_assist(
131131 target,
132132 |builder| {
133133 let insert_after = ted:: Position :: after ( builder. make_mut ( adt. clone ( ) ) . syntax ( ) ) ;
134-
134+ let impl_is_unsafe = trait_ . map ( |s| s . is_unsafe ( ctx . db ( ) ) ) . unwrap_or ( false ) ;
135135 let impl_def_with_items =
136136 impl_def_from_trait ( & ctx. sema , adt, & annotated_name, trait_, replace_trait_path) ;
137137 update_attribute ( builder, old_derives, old_tree, old_trait_path, attr) ;
@@ -141,13 +141,25 @@ fn add_assist(
141141 match ( ctx. config . snippet_cap , impl_def_with_items) {
142142 ( None , None ) => {
143143 let impl_def = generate_trait_impl ( adt, trait_path) ;
144+ if impl_is_unsafe {
145+ ted:: insert (
146+ Position :: first_child_of ( impl_def. syntax ( ) ) ,
147+ make:: token ( T ! [ unsafe ] ) ,
148+ ) ;
149+ }
144150
145151 ted:: insert_all (
146152 insert_after,
147153 vec ! [ make:: tokens:: blank_line( ) . into( ) , impl_def. syntax( ) . clone( ) . into( ) ] ,
148154 ) ;
149155 }
150156 ( None , Some ( ( impl_def, _) ) ) => {
157+ if impl_is_unsafe {
158+ ted:: insert (
159+ Position :: first_child_of ( impl_def. syntax ( ) ) ,
160+ make:: token ( T ! [ unsafe ] ) ,
161+ ) ;
162+ }
151163 ted:: insert_all (
152164 insert_after,
153165 vec ! [ make:: tokens:: blank_line( ) . into( ) , impl_def. syntax( ) . clone( ) . into( ) ] ,
@@ -156,6 +168,13 @@ fn add_assist(
156168 ( Some ( cap) , None ) => {
157169 let impl_def = generate_trait_impl ( adt, trait_path) ;
158170
171+ if impl_is_unsafe {
172+ ted:: insert (
173+ Position :: first_child_of ( impl_def. syntax ( ) ) ,
174+ make:: token ( T ! [ unsafe ] ) ,
175+ ) ;
176+ }
177+
159178 if let Some ( l_curly) =
160179 impl_def. assoc_item_list ( ) . and_then ( |it| it. l_curly_token ( ) )
161180 {
@@ -169,6 +188,14 @@ fn add_assist(
169188 }
170189 ( Some ( cap) , Some ( ( impl_def, first_assoc_item) ) ) => {
171190 let mut added_snippet = false ;
191+
192+ if impl_is_unsafe {
193+ ted:: insert (
194+ Position :: first_child_of ( impl_def. syntax ( ) ) ,
195+ make:: token ( T ! [ unsafe ] ) ,
196+ ) ;
197+ }
198+
172199 if let ast:: AssocItem :: Fn ( ref func) = first_assoc_item {
173200 if let Some ( m) = func. syntax ( ) . descendants ( ) . find_map ( ast:: MacroCall :: cast)
174201 {
@@ -1402,6 +1429,23 @@ impl core::fmt::Debug for Foo {
14021429 f.debug_struct("Foo").finish()
14031430 }
14041431}
1432+ "# ,
1433+ )
1434+ }
1435+
1436+ #[ test]
1437+ fn unsafeness_of_a_trait_observed ( ) {
1438+ check_assist (
1439+ replace_derive_with_manual_impl,
1440+ r#"
1441+ //- minicore: send, derive
1442+ #[derive(Sen$0d)]
1443+ pub struct Foo;
1444+ "# ,
1445+ r#"
1446+ pub struct Foo;
1447+
1448+ unsafe impl Send for Foo {$0}
14051449"# ,
14061450 )
14071451 }
0 commit comments