@@ -216,6 +216,14 @@ fn show_fieldless_enum(
216
216
substr : & Substructure < ' _ > ,
217
217
) -> BlockOrExpr {
218
218
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
+ }
219
227
let arms = def
220
228
. variants
221
229
. iter ( )
@@ -236,6 +244,47 @@ fn show_fieldless_enum(
236
244
} )
237
245
. collect :: < ThinVec < _ > > ( ) ;
238
246
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] ) ;
240
247
BlockOrExpr :: new_expr ( cx. expr_call_global ( span, fn_path_write_str, thin_vec ! [ fmt, name] ) )
241
248
}
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