@@ -2,8 +2,8 @@ use crate::deriving::generic::ty::*;
2
2
use crate :: deriving:: generic:: * ;
3
3
use crate :: deriving:: path_std;
4
4
5
- use ast :: EnumDef ;
6
- use rustc_ast :: { self as ast , MetaItem } ;
5
+ use rustc_ast :: { self as ast , token , EnumDef , ExprKind , MetaItem , TyKind } ;
6
+
7
7
use rustc_expand:: base:: { Annotatable , ExtCtxt } ;
8
8
use rustc_span:: symbol:: { sym, Ident , Symbol } ;
9
9
use rustc_span:: Span ;
@@ -152,15 +152,13 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
152
152
let path_debug = cx. path_global ( span, cx. std_path ( & [ sym:: fmt, sym:: Debug ] ) ) ;
153
153
let ty_dyn_debug = cx. ty (
154
154
span,
155
- ast :: TyKind :: TraitObject (
155
+ TyKind :: TraitObject (
156
156
vec ! [ cx. trait_bound( path_debug, false ) ] ,
157
157
ast:: TraitObjectSyntax :: Dyn ,
158
158
) ,
159
159
) ;
160
- let ty_slice = cx. ty (
161
- span,
162
- ast:: TyKind :: Slice ( cx. ty_ref ( span, ty_dyn_debug, None , ast:: Mutability :: Not ) ) ,
163
- ) ;
160
+ let ty_slice =
161
+ cx. ty ( span, TyKind :: Slice ( cx. ty_ref ( span, ty_dyn_debug, None , ast:: Mutability :: Not ) ) ) ;
164
162
let values_let = cx. stmt_let_ty (
165
163
span,
166
164
false ,
@@ -251,7 +249,10 @@ fn show_fieldless_enum(
251
249
/// ```text
252
250
/// impl ::core::fmt::Debug for A {
253
251
/// fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
254
- /// ::core::fmt::Formatter::write_str(f, ["A", "B", "C"][*self as usize])
252
+ /// ::core::fmt::Formatter::write_str(f, {
253
+ /// const __NAMES: [&str; 3] = ["A", "B", "C"];
254
+ /// __NAMES[::core::intrinsics::discriminant_value(self) as usize]
255
+ /// })
255
256
/// }
256
257
/// }
257
258
/// ```
@@ -260,31 +261,55 @@ fn show_fieldless_enum_array(
260
261
span : Span ,
261
262
def : & EnumDef ,
262
263
) -> 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
264
if def. variants . len ( ) >= cx. sess . target . pointer_width as usize {
270
265
return None ;
271
266
}
272
- // FIXME(clubby789): handle enums with discriminants matching their indexes
273
- let name_array = def
267
+ let names = def
274
268
. variants
275
269
. iter ( )
276
270
. map ( |v| if v. disr_expr . is_none ( ) { Some ( cx. expr_str ( span, v. ident . name ) ) } else { None } )
277
271
. collect :: < Option < ThinVec < _ > > > ( ) ?;
278
- let name = cx. expr (
272
+ let str_ty = cx. ty (
279
273
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
- ) ,
274
+ TyKind :: Ref (
275
+ None ,
276
+ ast:: MutTy {
277
+ ty : cx. ty (
278
+ span,
279
+ TyKind :: Path ( None , ast:: Path :: from_ident ( Ident :: new ( sym:: str, span) ) ) ,
280
+ ) ,
281
+ mutbl : ast:: Mutability :: Not ,
282
+ } ,
287
283
) ,
288
284
) ;
289
- Some ( name)
285
+
286
+ let size = cx. anon_const (
287
+ span,
288
+ ExprKind :: Lit ( token:: Lit :: new (
289
+ token:: LitKind :: Integer ,
290
+ Symbol :: intern ( & def. variants . len ( ) . to_string ( ) ) ,
291
+ None ,
292
+ ) ) ,
293
+ ) ;
294
+ // Create a constant to prevent the array being stack-allocated
295
+ let arr_name = Ident :: from_str_and_span ( "__NAMES" , span) ;
296
+ let names_const = cx. item_const (
297
+ span,
298
+ arr_name,
299
+ cx. ty ( span, TyKind :: Array ( str_ty, size) ) ,
300
+ cx. expr_array ( span, names) ,
301
+ ) ;
302
+ let discrim_value = cx. std_path ( & [ sym:: intrinsics, sym:: discriminant_value] ) ;
303
+
304
+ let index = cx. expr_cast (
305
+ span,
306
+ cx. expr_call_global ( span, discrim_value, thin_vec ! [ cx. expr_self( span) ] ) ,
307
+ cx. ty_path ( ast:: Path :: from_ident ( Ident :: new ( sym:: usize, span) ) ) ,
308
+ ) ;
309
+ let name = cx. expr ( span, ExprKind :: Index ( cx. expr_ident ( span, arr_name) , index) ) ;
310
+ Some (
311
+ cx. expr_block (
312
+ cx. block ( span, thin_vec ! [ cx. stmt_item( span, names_const) , cx. stmt_expr( name) ] ) ,
313
+ ) ,
314
+ )
290
315
}
0 commit comments