@@ -129,9 +129,6 @@ fn add_assist(
129129 let mut cursor = Cursor :: Before ( first_assoc_item. syntax ( ) ) ;
130130 let placeholder;
131131 if let ast:: AssocItem :: Fn ( ref func) = first_assoc_item {
132- // need to know what kind of derive this is: if it's Derive Debug, special case it.
133- // the name of the struct
134- // list of fields of the struct
135132 if let Some ( m) = func. syntax ( ) . descendants ( ) . find_map ( ast:: MacroCall :: cast)
136133 {
137134 if m. syntax ( ) . text ( ) == "todo!()" {
@@ -170,10 +167,12 @@ fn impl_def_from_trait(
170167 let ( impl_def, first_assoc_item) =
171168 add_trait_assoc_items_to_impl ( sema, trait_items, trait_, impl_def, target_scope) ;
172169
170+ // Generate a default `impl` function body for the derived trait.
173171 if let ast:: AssocItem :: Fn ( func) = & first_assoc_item {
174- if trait_path. segment ( ) . unwrap ( ) . name_ref ( ) . unwrap ( ) . text ( ) == "Debug" {
175- gen_debug_impl ( adt, func, annotated_name) ;
176- }
172+ match trait_path. segment ( ) . unwrap ( ) . name_ref ( ) . unwrap ( ) . text ( ) . as_str ( ) {
173+ "Debug" => gen_debug_impl ( adt, func, annotated_name) ,
174+ _ => { } // => If we don't know about the trait, the function body is left as `todo!`.
175+ } ;
177176 }
178177 Some ( ( impl_def, first_assoc_item) )
179178}
@@ -183,31 +182,31 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn, annotated_name: &ast::Name) {
183182 match adt {
184183 ast:: Adt :: Union ( _) => { } // `Debug` cannot be derived for unions, so no default impl can be provided.
185184 ast:: Adt :: Enum ( enum_) => {
185+ // => match self { Self::Variant => write!(f, "Variant") }
186186 if let Some ( list) = enum_. variant_list ( ) {
187187 let mut arms = vec ! [ ] ;
188188 for variant in list. variants ( ) {
189- // => Self::<Variant>
190189 let name = variant. name ( ) . unwrap ( ) ;
191- let first = make:: ext:: ident_path ( "Self" ) ;
192- let second = make:: ext:: ident_path ( & format ! ( "{}" , name) ) ;
193- let pat = make:: path_pat ( make:: path_concat ( first, second) ) ;
194190
195- // => write!(f, "<Variant>")
191+ let left = make:: ext:: ident_path ( "Self" ) ;
192+ let right = make:: ext:: ident_path ( & format ! ( "{}" , name) ) ;
193+ let variant_name = make:: path_pat ( make:: path_concat ( left, right) ) ;
194+
196195 let target = make:: expr_path ( make:: ext:: ident_path ( "f" ) . into ( ) ) ;
197196 let fmt_string = make:: expr_literal ( & ( format ! ( "\" {}\" " , name) ) ) . into ( ) ;
198197 let args = make:: arg_list ( vec ! [ target, fmt_string] ) ;
199- let target = make:: expr_path ( make:: ext:: ident_path ( "write" ) ) ;
200- let expr = make:: expr_macro_call ( target , args) ;
198+ let macro_name = make:: expr_path ( make:: ext:: ident_path ( "write" ) ) ;
199+ let macro_call = make:: expr_macro_call ( macro_name , args) ;
201200
202- arms. push ( make:: match_arm ( Some ( pat . into ( ) ) , None , expr . into ( ) ) ) ;
201+ arms. push ( make:: match_arm ( Some ( variant_name . into ( ) ) , None , macro_call . into ( ) ) ) ;
203202 }
204203
205- // => match self { ... }
206- let f_path = make:: expr_path ( make:: ext:: ident_path ( "self" ) ) ;
204+ let match_target = make:: expr_path ( make:: ext:: ident_path ( "self" ) ) ;
207205 let list = make:: match_arm_list ( arms) . indent ( ast:: edit:: IndentLevel ( 1 ) ) ;
208- let expr = make:: expr_match ( f_path , list) ;
206+ let match_expr = make:: expr_match ( match_target , list) ;
209207
210- let body = make:: block_expr ( None , Some ( expr) ) . indent ( ast:: edit:: IndentLevel ( 1 ) ) ;
208+ let body = make:: block_expr ( None , Some ( match_expr) ) ;
209+ let body = body. indent ( ast:: edit:: IndentLevel ( 1 ) ) ;
211210 ted:: replace ( func. body ( ) . unwrap ( ) . syntax ( ) , body. clone_for_update ( ) . syntax ( ) ) ;
212211 }
213212 }
@@ -217,8 +216,12 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn, annotated_name: &ast::Name) {
217216 let target = make:: expr_path ( make:: ext:: ident_path ( "f" ) ) ;
218217
219218 let expr = match strukt. field_list ( ) {
220- None => make:: expr_method_call ( target, "debug_struct" , args) ,
219+ None => {
220+ // => f.debug_struct("Name").finish()
221+ make:: expr_method_call ( target, "debug_struct" , args)
222+ }
221223 Some ( ast:: FieldList :: RecordFieldList ( field_list) ) => {
224+ // => f.debug_struct("Name").field("foo", &self.foo).finish()
222225 let mut expr = make:: expr_method_call ( target, "debug_struct" , args) ;
223226 for field in field_list. fields ( ) {
224227 if let Some ( name) = field. name ( ) {
@@ -233,6 +236,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn, annotated_name: &ast::Name) {
233236 expr
234237 }
235238 Some ( ast:: FieldList :: TupleFieldList ( field_list) ) => {
239+ // => f.debug_tuple("Name").field(self.0).finish()
236240 let mut expr = make:: expr_method_call ( target, "debug_tuple" , args) ;
237241 for ( idx, _) in field_list. fields ( ) . enumerate ( ) {
238242 let f_path = make:: expr_path ( make:: ext:: ident_path ( "self" ) ) ;
0 commit comments