@@ -10,11 +10,142 @@ mod attributes;
10
10
mod stability;
11
11
mod version;
12
12
13
+ use std:: num:: NonZero ;
14
+
13
15
pub use attributes:: * ;
16
+ use rustc_abi:: Align ;
17
+ use rustc_ast:: token:: CommentKind ;
18
+ use rustc_ast:: { AttrStyle , IntTy , UintTy } ;
19
+ use rustc_ast_pretty:: pp:: Printer ;
20
+ use rustc_span:: hygiene:: Transparency ;
21
+ use rustc_span:: { Span , Symbol } ;
14
22
pub use stability:: * ;
23
+ use thin_vec:: ThinVec ;
15
24
pub use version:: * ;
16
25
17
26
/// Requirements for a `StableHashingContext` to be used in this crate.
18
27
/// This is a hack to allow using the `HashStable_Generic` derive macro
19
28
/// instead of implementing everything in `rustc_middle`.
20
29
pub trait HashStableContext : rustc_ast:: HashStableContext + rustc_abi:: HashStableContext { }
30
+
31
+ /// This trait is used to print attributes in `rustc_hir_pretty`.
32
+ ///
33
+ /// For structs and enums it can be derived using [`rustc_macros::PrintAttribute`].
34
+ /// The output will look a lot like a `Debug` implementation, but fields of several types
35
+ /// like [`Span`]s and empty tuples, are gracefully skipped so they don't clutter the
36
+ /// representation much.
37
+ pub trait PrintAttribute {
38
+ fn print_something ( & self ) -> bool ;
39
+ fn print_attribute ( & self , p : & mut Printer ) ;
40
+ }
41
+
42
+ impl < T : PrintAttribute > PrintAttribute for & T {
43
+ fn print_something ( & self ) -> bool {
44
+ T :: print_something ( self )
45
+ }
46
+
47
+ fn print_attribute ( & self , p : & mut Printer ) {
48
+ T :: print_attribute ( self , p)
49
+ }
50
+ }
51
+ impl < T : PrintAttribute > PrintAttribute for Option < T > {
52
+ fn print_something ( & self ) -> bool {
53
+ self . as_ref ( ) . is_some_and ( |x| x. print_something ( ) )
54
+ }
55
+ fn print_attribute ( & self , p : & mut Printer ) {
56
+ if let Some ( i) = self {
57
+ T :: print_attribute ( i, p)
58
+ }
59
+ }
60
+ }
61
+ impl < T : PrintAttribute > PrintAttribute for ThinVec < T > {
62
+ fn print_something ( & self ) -> bool {
63
+ self . is_empty ( ) || self [ 0 ] . print_something ( )
64
+ }
65
+ fn print_attribute ( & self , p : & mut Printer ) {
66
+ let mut last_printed = false ;
67
+ p. word ( "[" ) ;
68
+ for i in self {
69
+ if last_printed {
70
+ p. word_space ( "," ) ;
71
+ }
72
+ i. print_attribute ( p) ;
73
+ last_printed = i. print_something ( ) ;
74
+ }
75
+ p. word ( "]" ) ;
76
+ }
77
+ }
78
+ macro_rules! print_skip {
79
+ ( $( $t: ty) ,* $( , ) ?) => { $(
80
+ impl PrintAttribute for $t {
81
+ fn print_something( & self ) -> bool { false }
82
+ fn print_attribute( & self , _: & mut Printer ) { }
83
+ } ) *
84
+ } ;
85
+ }
86
+
87
+ macro_rules! print_disp {
88
+ ( $( $t: ty) ,* $( , ) ?) => { $(
89
+ impl PrintAttribute for $t {
90
+ fn print_something( & self ) -> bool { true }
91
+ fn print_attribute( & self , p: & mut Printer ) {
92
+ p. word( format!( "{}" , self ) ) ;
93
+ }
94
+ }
95
+ ) * } ;
96
+ }
97
+ macro_rules! print_debug {
98
+ ( $( $t: ty) ,* $( , ) ?) => { $(
99
+ impl PrintAttribute for $t {
100
+ fn print_something( & self ) -> bool { true }
101
+ fn print_attribute( & self , p: & mut Printer ) {
102
+ p. word( format!( "{:?}" , self ) ) ;
103
+ }
104
+ }
105
+ ) * } ;
106
+ }
107
+
108
+ macro_rules! print_tup {
109
+ ( num_print_something $( $ts: ident) * ) => { 0 $( + $ts. print_something( ) as usize ) * } ;
110
+ ( ) => { } ;
111
+ ( $t: ident $( $ts: ident) * ) => {
112
+ #[ allow( non_snake_case, unused) ]
113
+ impl <$t: PrintAttribute , $( $ts: PrintAttribute ) ,* > PrintAttribute for ( $t, $( $ts) ,* ) {
114
+ fn print_something( & self ) -> bool {
115
+ let ( $t, $( $ts) ,* ) = self ;
116
+ print_tup!( num_print_something $t $( $ts) * ) != 0
117
+ }
118
+
119
+ fn print_attribute( & self , p: & mut Printer ) {
120
+ let ( $t, $( $ts) ,* ) = self ;
121
+ let parens = print_tup!( num_print_something $t $( $ts) * ) > 1 ;
122
+ if parens {
123
+ p. word( "(" ) ;
124
+ }
125
+
126
+ let mut printed_anything = $t. print_something( ) ;
127
+
128
+ $t. print_attribute( p) ;
129
+
130
+ $(
131
+ if printed_anything && $ts. print_something( ) {
132
+ p. word_space( "," ) ;
133
+ printed_anything = true ;
134
+ }
135
+ $ts. print_attribute( p) ;
136
+ ) *
137
+
138
+ if parens {
139
+ p. word( ")" ) ;
140
+ }
141
+ }
142
+ }
143
+
144
+ print_tup!( $( $ts) * ) ;
145
+ } ;
146
+ }
147
+
148
+ print_tup ! ( A B C D E F G H ) ;
149
+ print_skip ! ( Span , ( ) ) ;
150
+ print_disp ! ( Symbol , u16 , bool , NonZero <u32 >) ;
151
+ print_debug ! ( UintTy , IntTy , Align , AttrStyle , CommentKind , Transparency ) ;
0 commit comments