@@ -10,11 +10,142 @@ mod attributes;
1010mod stability;
1111mod version;
1212
13+ use std:: num:: NonZero ;
14+
1315pub 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 } ;
1422pub use stability:: * ;
23+ use thin_vec:: ThinVec ;
1524pub use version:: * ;
1625
1726/// Requirements for a `StableHashingContext` to be used in this crate.
1827/// This is a hack to allow using the `HashStable_Generic` derive macro
1928/// instead of implementing everything in `rustc_middle`.
2029pub 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