@@ -43,6 +43,7 @@ use std::iter::Peekable;
4343use std:: path:: PathBuf ;
4444use std:: { fs, str} ;
4545
46+ use itertools:: Either ;
4647use rinja:: Template ;
4748use rustc_attr_parsing:: {
4849 ConstStability , DeprecatedSince , Deprecation , RustcVersion , StabilityLevel , StableSince ,
@@ -1645,8 +1646,8 @@ fn render_impl(
16451646 // `containing_item` is used for rendering stability info. If the parent is a trait impl,
16461647 // `containing_item` will the grandparent, since trait impls can't have stability attached.
16471648 fn doc_impl_item (
1648- boring : & mut String ,
1649- interesting : & mut String ,
1649+ boring : impl fmt :: Write ,
1650+ interesting : impl fmt :: Write ,
16501651 cx : & Context < ' _ > ,
16511652 item : & clean:: Item ,
16521653 parent : & clean:: Item ,
@@ -1655,7 +1656,7 @@ fn render_impl(
16551656 is_default_item : bool ,
16561657 trait_ : Option < & clean:: Trait > ,
16571658 rendering_params : ImplRenderingParameters ,
1658- ) {
1659+ ) -> fmt :: Result {
16591660 let item_type = item. type_ ( ) ;
16601661 let name = item. name . as_ref ( ) . unwrap ( ) ;
16611662
@@ -1730,15 +1731,16 @@ fn render_impl(
17301731 ) ;
17311732 }
17321733 }
1733- let w = if short_documented && trait_. is_some ( ) { interesting } else { boring } ;
1734+ let mut w = if short_documented && trait_. is_some ( ) {
1735+ Either :: Left ( interesting)
1736+ } else {
1737+ Either :: Right ( boring)
1738+ } ;
17341739
17351740 let toggled = !doc_buffer. is_empty ( ) ;
17361741 if toggled {
17371742 let method_toggle_class = if item_type. is_method ( ) { " method-toggle" } else { "" } ;
1738- write_str (
1739- w,
1740- format_args ! ( "<details class=\" toggle{method_toggle_class}\" open><summary>" ) ,
1741- ) ;
1743+ write ! ( w, "<details class=\" toggle{method_toggle_class}\" open><summary>" ) ?;
17421744 }
17431745 match & item. kind {
17441746 clean:: MethodItem ( ..) | clean:: RequiredMethodItem ( _) => {
@@ -1753,172 +1755,151 @@ fn render_impl(
17531755 . find ( |item| item. name . map ( |n| n == * name) . unwrap_or ( false ) )
17541756 } )
17551757 . map ( |item| format ! ( "{}.{name}" , item. type_( ) ) ) ;
1756- write_str (
1758+ write ! (
17571759 w,
1758- format_args ! (
1759- "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
1760+ "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
17601761 {}",
1761- render_rightside( cx, item, render_mode)
1762- ) ,
1763- ) ;
1762+ render_rightside( cx, item, render_mode)
1763+ ) ?;
17641764 if trait_. is_some ( ) {
17651765 // Anchors are only used on trait impls.
1766- write_str ( w, format_args ! ( "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ) ;
1766+ write ! ( w, "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ? ;
17671767 }
1768- write_str (
1768+ write ! (
17691769 w,
1770- format_args ! (
1771- "<h4 class=\" code-header\" >{}</h4></section>" ,
1772- render_assoc_item(
1773- item,
1774- link. anchor( source_id. as_ref( ) . unwrap_or( & id) ) ,
1775- ItemType :: Impl ,
1776- cx,
1777- render_mode,
1778- ) ,
1770+ "<h4 class=\" code-header\" >{}</h4></section>" ,
1771+ render_assoc_item(
1772+ item,
1773+ link. anchor( source_id. as_ref( ) . unwrap_or( & id) ) ,
1774+ ItemType :: Impl ,
1775+ cx,
1776+ render_mode,
17791777 ) ,
1780- ) ;
1778+ ) ? ;
17811779 }
17821780 }
17831781 clean:: RequiredAssocConstItem ( generics, ty) => {
17841782 let source_id = format ! ( "{item_type}.{name}" ) ;
17851783 let id = cx. derive_id ( & source_id) ;
1786- write_str (
1784+ write ! (
17871785 w,
1788- format_args ! (
1789- "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
1786+ "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
17901787 {}",
1791- render_rightside( cx, item, render_mode)
1792- ) ,
1793- ) ;
1788+ render_rightside( cx, item, render_mode)
1789+ ) ?;
17941790 if trait_. is_some ( ) {
17951791 // Anchors are only used on trait impls.
1796- write_str ( w, format_args ! ( "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ) ;
1792+ write ! ( w, "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ? ;
17971793 }
1798- write_str (
1794+ write ! (
17991795 w,
1800- format_args ! (
1801- "<h4 class=\" code-header\" >{}</h4></section>" ,
1802- assoc_const(
1803- item,
1804- generics,
1805- ty,
1806- AssocConstValue :: None ,
1807- link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1808- 0 ,
1809- cx,
1810- )
1796+ "<h4 class=\" code-header\" >{}</h4></section>" ,
1797+ assoc_const(
1798+ item,
1799+ generics,
1800+ ty,
1801+ AssocConstValue :: None ,
1802+ link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1803+ 0 ,
1804+ cx,
18111805 ) ,
1812- ) ;
1806+ ) ? ;
18131807 }
18141808 clean:: ProvidedAssocConstItem ( ci) | clean:: ImplAssocConstItem ( ci) => {
18151809 let source_id = format ! ( "{item_type}.{name}" ) ;
18161810 let id = cx. derive_id ( & source_id) ;
1817- write_str (
1811+ write ! (
18181812 w,
1819- format_args ! (
1820- "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
1813+ "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
18211814 {}",
1822- render_rightside( cx, item, render_mode)
1823- ) ,
1824- ) ;
1815+ render_rightside( cx, item, render_mode) ,
1816+ ) ?;
18251817 if trait_. is_some ( ) {
18261818 // Anchors are only used on trait impls.
1827- write_str ( w, format_args ! ( "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ) ;
1819+ write ! ( w, "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ? ;
18281820 }
1829- write_str (
1821+ write ! (
18301822 w,
1831- format_args ! (
1832- "<h4 class=\" code-header\" >{}</h4></section>" ,
1833- assoc_const(
1834- item,
1835- & ci. generics,
1836- & ci. type_,
1837- match item. kind {
1838- clean:: ProvidedAssocConstItem ( _) =>
1839- AssocConstValue :: TraitDefault ( & ci. kind) ,
1840- clean:: ImplAssocConstItem ( _) => AssocConstValue :: Impl ( & ci. kind) ,
1841- _ => unreachable!( ) ,
1842- } ,
1843- link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1844- 0 ,
1845- cx,
1846- )
1823+ "<h4 class=\" code-header\" >{}</h4></section>" ,
1824+ assoc_const(
1825+ item,
1826+ & ci. generics,
1827+ & ci. type_,
1828+ match item. kind {
1829+ clean:: ProvidedAssocConstItem ( _) =>
1830+ AssocConstValue :: TraitDefault ( & ci. kind) ,
1831+ clean:: ImplAssocConstItem ( _) => AssocConstValue :: Impl ( & ci. kind) ,
1832+ _ => unreachable!( ) ,
1833+ } ,
1834+ link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1835+ 0 ,
1836+ cx,
18471837 ) ,
1848- ) ;
1838+ ) ? ;
18491839 }
18501840 clean:: RequiredAssocTypeItem ( generics, bounds) => {
18511841 let source_id = format ! ( "{item_type}.{name}" ) ;
18521842 let id = cx. derive_id ( & source_id) ;
1853- write_str (
1843+ write ! (
18541844 w,
1855- format_args ! (
1856- "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
1845+ "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
18571846 {}",
1858- render_rightside( cx, item, render_mode)
1859- ) ,
1860- ) ;
1847+ render_rightside( cx, item, render_mode) ,
1848+ ) ?;
18611849 if trait_. is_some ( ) {
18621850 // Anchors are only used on trait impls.
1863- write_str ( w, format_args ! ( "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ) ;
1851+ write ! ( w, "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ? ;
18641852 }
1865- write_str (
1853+ write ! (
18661854 w,
1867- format_args ! (
1868- "<h4 class=\" code-header\" >{}</h4></section>" ,
1869- assoc_type(
1870- item,
1871- generics,
1872- bounds,
1873- None ,
1874- link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1875- 0 ,
1876- cx,
1877- )
1855+ "<h4 class=\" code-header\" >{}</h4></section>" ,
1856+ assoc_type(
1857+ item,
1858+ generics,
1859+ bounds,
1860+ None ,
1861+ link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1862+ 0 ,
1863+ cx,
18781864 ) ,
1879- ) ;
1865+ ) ? ;
18801866 }
18811867 clean:: AssocTypeItem ( tydef, _bounds) => {
18821868 let source_id = format ! ( "{item_type}.{name}" ) ;
18831869 let id = cx. derive_id ( & source_id) ;
1884- write_str (
1870+ write ! (
18851871 w,
1886- format_args ! (
1887- "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
1872+ "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
18881873 {}",
1889- render_rightside( cx, item, render_mode)
1890- ) ,
1891- ) ;
1874+ render_rightside( cx, item, render_mode) ,
1875+ ) ?;
18921876 if trait_. is_some ( ) {
18931877 // Anchors are only used on trait impls.
1894- write_str ( w, format_args ! ( "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ) ;
1878+ write ! ( w, "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ? ;
18951879 }
1896- write_str (
1880+ write ! (
18971881 w,
1898- format_args ! (
1899- "<h4 class=\" code-header\" >{}</h4></section>" ,
1900- assoc_type(
1901- item,
1902- & tydef. generics,
1903- & [ ] , // intentionally leaving out bounds
1904- Some ( tydef. item_type. as_ref( ) . unwrap_or( & tydef. type_) ) ,
1905- link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1906- 0 ,
1907- cx,
1908- )
1882+ "<h4 class=\" code-header\" >{}</h4></section>" ,
1883+ assoc_type(
1884+ item,
1885+ & tydef. generics,
1886+ & [ ] , // intentionally leaving out bounds
1887+ Some ( tydef. item_type. as_ref( ) . unwrap_or( & tydef. type_) ) ,
1888+ link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1889+ 0 ,
1890+ cx,
19091891 ) ,
1910- ) ;
1892+ ) ? ;
19111893 }
1912- clean:: StrippedItem ( ..) => return ,
1894+ clean:: StrippedItem ( ..) => return Ok ( ( ) ) ,
19131895 _ => panic ! ( "can't make docs for trait item with name {:?}" , item. name) ,
19141896 }
19151897
1916- w. push_str ( & info_buffer) ;
1898+ w. write_str ( & info_buffer) ? ;
19171899 if toggled {
1918- w. push_str ( "</summary>" ) ;
1919- w. push_str ( & doc_buffer) ;
1920- w. push_str ( "</details>" ) ;
1900+ write ! ( w, "</summary>{doc_buffer}</details>" ) ?;
19211901 }
1902+ Ok ( ( ) )
19221903 }
19231904
19241905 let mut impl_items = String :: new ( ) ;
@@ -1961,7 +1942,7 @@ fn render_impl(
19611942 false ,
19621943 trait_,
19631944 rendering_params,
1964- ) ;
1945+ ) ? ;
19651946 }
19661947 _ => { }
19671948 }
@@ -1979,7 +1960,7 @@ fn render_impl(
19791960 false ,
19801961 trait_,
19811962 rendering_params,
1982- ) ;
1963+ ) ? ;
19831964 }
19841965 for method in methods {
19851966 doc_impl_item (
@@ -1993,20 +1974,20 @@ fn render_impl(
19931974 false ,
19941975 trait_,
19951976 rendering_params,
1996- ) ;
1977+ ) ? ;
19971978 }
19981979 }
19991980
20001981 fn render_default_items (
2001- boring : & mut String ,
2002- interesting : & mut String ,
1982+ mut boring : impl fmt :: Write ,
1983+ mut interesting : impl fmt :: Write ,
20031984 cx : & Context < ' _ > ,
20041985 t : & clean:: Trait ,
20051986 i : & clean:: Impl ,
20061987 parent : & clean:: Item ,
20071988 render_mode : RenderMode ,
20081989 rendering_params : ImplRenderingParameters ,
2009- ) {
1990+ ) -> fmt :: Result {
20101991 for trait_item in & t. items {
20111992 // Skip over any default trait items that are impossible to reference
20121993 // (e.g. if it has a `Self: Sized` bound on an unsized type).
@@ -2026,8 +2007,8 @@ fn render_impl(
20262007 let assoc_link = AssocItemLink :: GotoSource ( did. into ( ) , & provided_methods) ;
20272008
20282009 doc_impl_item (
2029- boring,
2030- interesting,
2010+ & mut boring,
2011+ & mut interesting,
20312012 cx,
20322013 trait_item,
20332014 parent,
@@ -2036,8 +2017,9 @@ fn render_impl(
20362017 true ,
20372018 Some ( t) ,
20382019 rendering_params,
2039- ) ;
2020+ ) ? ;
20402021 }
2022+ Ok ( ( ) )
20412023 }
20422024
20432025 // If we've implemented a trait, then also emit documentation for all
@@ -2057,7 +2039,7 @@ fn render_impl(
20572039 & i. impl_item ,
20582040 render_mode,
20592041 rendering_params,
2060- ) ;
2042+ ) ? ;
20612043 }
20622044 }
20632045 if render_mode == RenderMode :: Normal {
0 commit comments