@@ -3,10 +3,12 @@ use crate::clean::blanket_impl::BlanketImplFinder;
33use crate :: clean:: {
44 inline, Clean , Crate , Generic , GenericArg , GenericArgs , ImportSource , Item , ItemKind , Lifetime ,
55 Path , PathSegment , PolyTrait , Primitive , PrimitiveType , ResolvedPath , Type , TypeBinding ,
6+ Visibility ,
67} ;
78use crate :: core:: DocContext ;
89use crate :: formats:: item_type:: ItemType ;
910
11+ use rustc_ast as ast;
1012use rustc_ast:: tokenstream:: TokenTree ;
1113use rustc_hir as hir;
1214use rustc_hir:: def:: { DefKind , Res } ;
@@ -577,3 +579,37 @@ pub(super) fn render_macro_arms<'a>(
577579pub ( super ) fn render_macro_matcher ( matcher : & TokenTree ) -> String {
578580 rustc_ast_pretty:: pprust:: tt_to_string ( matcher)
579581}
582+
583+ pub ( super ) fn display_macro_source (
584+ cx : & mut DocContext < ' _ > ,
585+ name : Symbol ,
586+ def : & ast:: MacroDef ,
587+ def_id : DefId ,
588+ vis : impl Clean < Visibility > ,
589+ ) -> String {
590+ let tts: Vec < _ > = def. body . inner_tokens ( ) . into_trees ( ) . collect ( ) ;
591+ // Extract the spans of all matchers. They represent the "interface" of the macro.
592+ let matchers = tts. chunks ( 4 ) . map ( |arm| & arm[ 0 ] ) ;
593+
594+ if def. macro_rules {
595+ format ! ( "macro_rules! {} {{\n {}}}" , name, render_macro_arms( matchers, ";" ) )
596+ } else {
597+ let vis = vis. clean ( cx) ;
598+
599+ if matchers. len ( ) <= 1 {
600+ format ! (
601+ "{}macro {}{} {{\n ...\n }}" ,
602+ vis. to_src_with_space( cx. tcx, def_id) ,
603+ name,
604+ matchers. map( render_macro_matcher) . collect:: <String >( ) ,
605+ )
606+ } else {
607+ format ! (
608+ "{}macro {} {{\n {}}}" ,
609+ vis. to_src_with_space( cx. tcx, def_id) ,
610+ name,
611+ render_macro_arms( matchers, "," ) ,
612+ )
613+ }
614+ }
615+ }
0 commit comments