@@ -216,6 +216,14 @@ fn show_fieldless_enum(
216216 substr : & Substructure < ' _ > ,
217217) -> BlockOrExpr {
218218 let fmt = substr. nonselflike_args [ 0 ] . clone ( ) ;
219+ let fn_path_write_str = cx. std_path ( & [ sym:: fmt, sym:: Formatter , sym:: write_str] ) ;
220+ if let Some ( name) = show_fieldless_enum_array ( cx, span, def) {
221+ return BlockOrExpr :: new_expr ( cx. expr_call_global (
222+ span,
223+ fn_path_write_str,
224+ thin_vec ! [ fmt, name] ,
225+ ) ) ;
226+ }
219227 let arms = def
220228 . variants
221229 . iter ( )
@@ -236,6 +244,47 @@ fn show_fieldless_enum(
236244 } )
237245 . collect :: < ThinVec < _ > > ( ) ;
238246 let name = cx. expr_match ( span, cx. expr_self ( span) , arms) ;
239- let fn_path_write_str = cx. std_path ( & [ sym:: fmt, sym:: Formatter , sym:: write_str] ) ;
240247 BlockOrExpr :: new_expr ( cx. expr_call_global ( span, fn_path_write_str, thin_vec ! [ fmt, name] ) )
241248}
249+
250+ /// Specialer case for fieldless enums with no discriminants. Builds
251+ /// ```text
252+ /// impl ::core::fmt::Debug for A {
253+ /// fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
254+ /// ::core::fmt::Formatter::write_str(f, ["A", "B", "C"][*self as usize])
255+ /// }
256+ /// }
257+ /// ```
258+ fn show_fieldless_enum_array (
259+ cx : & mut ExtCtxt < ' _ > ,
260+ span : Span ,
261+ def : & EnumDef ,
262+ ) -> Option < ast:: ptr:: P < ast:: Expr > > {
263+ let container_id = cx. current_expansion . id . expn_data ( ) . parent . expect_local ( ) ;
264+ let has_derive_copy = cx. resolver . has_derive_copy ( container_id) ;
265+ // FIXME(clubby789): handle repr(xx) enums too
266+ if !has_derive_copy {
267+ return None ;
268+ }
269+ if def. variants . len ( ) >= cx. sess . target . pointer_width as usize {
270+ return None ;
271+ }
272+ // FIXME(clubby789): handle enums with discriminants matching their indexes
273+ let name_array = def
274+ . variants
275+ . iter ( )
276+ . map ( |v| if v. disr_expr . is_none ( ) { Some ( cx. expr_str ( span, v. ident . name ) ) } else { None } )
277+ . collect :: < Option < ThinVec < _ > > > ( ) ?;
278+ let name = cx. expr (
279+ span,
280+ ast:: ExprKind :: Index (
281+ cx. expr_array ( span, name_array) ,
282+ cx. expr_cast (
283+ span,
284+ cx. expr_deref ( span, cx. expr_self ( span) ) ,
285+ cx. ty_path ( ast:: Path :: from_ident ( Ident :: with_dummy_span ( sym:: usize) ) ) ,
286+ ) ,
287+ ) ,
288+ ) ;
289+ Some ( name)
290+ }
0 commit comments