@@ -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 ,
@@ -1647,8 +1648,8 @@ fn render_impl(
16471648 // `containing_item` is used for rendering stability info. If the parent is a trait impl,
16481649 // `containing_item` will the grandparent, since trait impls can't have stability attached.
16491650 fn doc_impl_item (
1650- boring : & mut String ,
1651- interesting : & mut String ,
1651+ boring : impl fmt :: Write ,
1652+ interesting : impl fmt :: Write ,
16521653 cx : & Context < ' _ > ,
16531654 item : & clean:: Item ,
16541655 parent : & clean:: Item ,
@@ -1657,7 +1658,7 @@ fn render_impl(
16571658 is_default_item : bool ,
16581659 trait_ : Option < & clean:: Trait > ,
16591660 rendering_params : ImplRenderingParameters ,
1660- ) {
1661+ ) -> fmt :: Result {
16611662 let item_type = item. type_ ( ) ;
16621663 let name = item. name . as_ref ( ) . unwrap ( ) ;
16631664
@@ -1732,15 +1733,16 @@ fn render_impl(
17321733 ) ;
17331734 }
17341735 }
1735- let w = if short_documented && trait_. is_some ( ) { interesting } else { boring } ;
1736+ let mut w = if short_documented && trait_. is_some ( ) {
1737+ Either :: Left ( interesting)
1738+ } else {
1739+ Either :: Right ( boring)
1740+ } ;
17361741
17371742 let toggled = !doc_buffer. is_empty ( ) ;
17381743 if toggled {
17391744 let method_toggle_class = if item_type. is_method ( ) { " method-toggle" } else { "" } ;
1740- write_str (
1741- w,
1742- format_args ! ( "<details class=\" toggle{method_toggle_class}\" open><summary>" ) ,
1743- ) ;
1745+ write ! ( w, "<details class=\" toggle{method_toggle_class}\" open><summary>" ) ?;
17441746 }
17451747 match & item. kind {
17461748 clean:: MethodItem ( ..) | clean:: RequiredMethodItem ( _) => {
@@ -1755,172 +1757,151 @@ fn render_impl(
17551757 . find ( |item| item. name . map ( |n| n == * name) . unwrap_or ( false ) )
17561758 } )
17571759 . map ( |item| format ! ( "{}.{name}" , item. type_( ) ) ) ;
1758- write_str (
1760+ write ! (
17591761 w,
1760- format_args ! (
1761- "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
1762+ "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
17621763 {}",
1763- render_rightside( cx, item, render_mode)
1764- ) ,
1765- ) ;
1764+ render_rightside( cx, item, render_mode)
1765+ ) ?;
17661766 if trait_. is_some ( ) {
17671767 // Anchors are only used on trait impls.
1768- write_str ( w, format_args ! ( "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ) ;
1768+ write ! ( w, "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ? ;
17691769 }
1770- write_str (
1770+ write ! (
17711771 w,
1772- format_args ! (
1773- "<h4 class=\" code-header\" >{}</h4></section>" ,
1774- render_assoc_item(
1775- item,
1776- link. anchor( source_id. as_ref( ) . unwrap_or( & id) ) ,
1777- ItemType :: Impl ,
1778- cx,
1779- render_mode,
1780- ) ,
1772+ "<h4 class=\" code-header\" >{}</h4></section>" ,
1773+ render_assoc_item(
1774+ item,
1775+ link. anchor( source_id. as_ref( ) . unwrap_or( & id) ) ,
1776+ ItemType :: Impl ,
1777+ cx,
1778+ render_mode,
17811779 ) ,
1782- ) ;
1780+ ) ? ;
17831781 }
17841782 }
17851783 clean:: RequiredAssocConstItem ( generics, ty) => {
17861784 let source_id = format ! ( "{item_type}.{name}" ) ;
17871785 let id = cx. derive_id ( & source_id) ;
1788- write_str (
1786+ write ! (
17891787 w,
1790- format_args ! (
1791- "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
1788+ "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
17921789 {}",
1793- render_rightside( cx, item, render_mode)
1794- ) ,
1795- ) ;
1790+ render_rightside( cx, item, render_mode)
1791+ ) ?;
17961792 if trait_. is_some ( ) {
17971793 // Anchors are only used on trait impls.
1798- write_str ( w, format_args ! ( "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ) ;
1794+ write ! ( w, "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ? ;
17991795 }
1800- write_str (
1796+ write ! (
18011797 w,
1802- format_args ! (
1803- "<h4 class=\" code-header\" >{}</h4></section>" ,
1804- assoc_const(
1805- item,
1806- generics,
1807- ty,
1808- AssocConstValue :: None ,
1809- link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1810- 0 ,
1811- cx,
1812- )
1798+ "<h4 class=\" code-header\" >{}</h4></section>" ,
1799+ assoc_const(
1800+ item,
1801+ generics,
1802+ ty,
1803+ AssocConstValue :: None ,
1804+ link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1805+ 0 ,
1806+ cx,
18131807 ) ,
1814- ) ;
1808+ ) ? ;
18151809 }
18161810 clean:: ProvidedAssocConstItem ( ci) | clean:: ImplAssocConstItem ( ci) => {
18171811 let source_id = format ! ( "{item_type}.{name}" ) ;
18181812 let id = cx. derive_id ( & source_id) ;
1819- write_str (
1813+ write ! (
18201814 w,
1821- format_args ! (
1822- "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
1815+ "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
18231816 {}",
1824- render_rightside( cx, item, render_mode)
1825- ) ,
1826- ) ;
1817+ render_rightside( cx, item, render_mode) ,
1818+ ) ?;
18271819 if trait_. is_some ( ) {
18281820 // Anchors are only used on trait impls.
1829- write_str ( w, format_args ! ( "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ) ;
1821+ write ! ( w, "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ? ;
18301822 }
1831- write_str (
1823+ write ! (
18321824 w,
1833- format_args ! (
1834- "<h4 class=\" code-header\" >{}</h4></section>" ,
1835- assoc_const(
1836- item,
1837- & ci. generics,
1838- & ci. type_,
1839- match item. kind {
1840- clean:: ProvidedAssocConstItem ( _) =>
1841- AssocConstValue :: TraitDefault ( & ci. kind) ,
1842- clean:: ImplAssocConstItem ( _) => AssocConstValue :: Impl ( & ci. kind) ,
1843- _ => unreachable!( ) ,
1844- } ,
1845- link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1846- 0 ,
1847- cx,
1848- )
1825+ "<h4 class=\" code-header\" >{}</h4></section>" ,
1826+ assoc_const(
1827+ item,
1828+ & ci. generics,
1829+ & ci. type_,
1830+ match item. kind {
1831+ clean:: ProvidedAssocConstItem ( _) =>
1832+ AssocConstValue :: TraitDefault ( & ci. kind) ,
1833+ clean:: ImplAssocConstItem ( _) => AssocConstValue :: Impl ( & ci. kind) ,
1834+ _ => unreachable!( ) ,
1835+ } ,
1836+ link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1837+ 0 ,
1838+ cx,
18491839 ) ,
1850- ) ;
1840+ ) ? ;
18511841 }
18521842 clean:: RequiredAssocTypeItem ( generics, bounds) => {
18531843 let source_id = format ! ( "{item_type}.{name}" ) ;
18541844 let id = cx. derive_id ( & source_id) ;
1855- write_str (
1845+ write ! (
18561846 w,
1857- format_args ! (
1858- "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
1847+ "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
18591848 {}",
1860- render_rightside( cx, item, render_mode)
1861- ) ,
1862- ) ;
1849+ render_rightside( cx, item, render_mode) ,
1850+ ) ?;
18631851 if trait_. is_some ( ) {
18641852 // Anchors are only used on trait impls.
1865- write_str ( w, format_args ! ( "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ) ;
1853+ write ! ( w, "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ? ;
18661854 }
1867- write_str (
1855+ write ! (
18681856 w,
1869- format_args ! (
1870- "<h4 class=\" code-header\" >{}</h4></section>" ,
1871- assoc_type(
1872- item,
1873- generics,
1874- bounds,
1875- None ,
1876- link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1877- 0 ,
1878- cx,
1879- )
1857+ "<h4 class=\" code-header\" >{}</h4></section>" ,
1858+ assoc_type(
1859+ item,
1860+ generics,
1861+ bounds,
1862+ None ,
1863+ link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1864+ 0 ,
1865+ cx,
18801866 ) ,
1881- ) ;
1867+ ) ? ;
18821868 }
18831869 clean:: AssocTypeItem ( tydef, _bounds) => {
18841870 let source_id = format ! ( "{item_type}.{name}" ) ;
18851871 let id = cx. derive_id ( & source_id) ;
1886- write_str (
1872+ write ! (
18871873 w,
1888- format_args ! (
1889- "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
1874+ "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
18901875 {}",
1891- render_rightside( cx, item, render_mode)
1892- ) ,
1893- ) ;
1876+ render_rightside( cx, item, render_mode) ,
1877+ ) ?;
18941878 if trait_. is_some ( ) {
18951879 // Anchors are only used on trait impls.
1896- write_str ( w, format_args ! ( "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ) ;
1880+ write ! ( w, "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ? ;
18971881 }
1898- write_str (
1882+ write ! (
18991883 w,
1900- format_args ! (
1901- "<h4 class=\" code-header\" >{}</h4></section>" ,
1902- assoc_type(
1903- item,
1904- & tydef. generics,
1905- & [ ] , // intentionally leaving out bounds
1906- Some ( tydef. item_type. as_ref( ) . unwrap_or( & tydef. type_) ) ,
1907- link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1908- 0 ,
1909- cx,
1910- )
1884+ "<h4 class=\" code-header\" >{}</h4></section>" ,
1885+ assoc_type(
1886+ item,
1887+ & tydef. generics,
1888+ & [ ] , // intentionally leaving out bounds
1889+ Some ( tydef. item_type. as_ref( ) . unwrap_or( & tydef. type_) ) ,
1890+ link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1891+ 0 ,
1892+ cx,
19111893 ) ,
1912- ) ;
1894+ ) ? ;
19131895 }
1914- clean:: StrippedItem ( ..) => return ,
1896+ clean:: StrippedItem ( ..) => return Ok ( ( ) ) ,
19151897 _ => panic ! ( "can't make docs for trait item with name {:?}" , item. name) ,
19161898 }
19171899
1918- w. push_str ( & info_buffer) ;
1900+ w. write_str ( & info_buffer) ? ;
19191901 if toggled {
1920- w. push_str ( "</summary>" ) ;
1921- w. push_str ( & doc_buffer) ;
1922- w. push_str ( "</details>" ) ;
1902+ write ! ( w, "</summary>{doc_buffer}</details>" ) ?;
19231903 }
1904+ Ok ( ( ) )
19241905 }
19251906
19261907 let mut impl_items = String :: new ( ) ;
@@ -1963,7 +1944,7 @@ fn render_impl(
19631944 false ,
19641945 trait_,
19651946 rendering_params,
1966- ) ;
1947+ ) ? ;
19671948 }
19681949 _ => { }
19691950 }
@@ -1981,7 +1962,7 @@ fn render_impl(
19811962 false ,
19821963 trait_,
19831964 rendering_params,
1984- ) ;
1965+ ) ? ;
19851966 }
19861967 for method in methods {
19871968 doc_impl_item (
@@ -1995,20 +1976,20 @@ fn render_impl(
19951976 false ,
19961977 trait_,
19971978 rendering_params,
1998- ) ;
1979+ ) ? ;
19991980 }
20001981 }
20011982
20021983 fn render_default_items (
2003- boring : & mut String ,
2004- interesting : & mut String ,
1984+ mut boring : impl fmt :: Write ,
1985+ mut interesting : impl fmt :: Write ,
20051986 cx : & Context < ' _ > ,
20061987 t : & clean:: Trait ,
20071988 i : & clean:: Impl ,
20081989 parent : & clean:: Item ,
20091990 render_mode : RenderMode ,
20101991 rendering_params : ImplRenderingParameters ,
2011- ) {
1992+ ) -> fmt :: Result {
20121993 for trait_item in & t. items {
20131994 // Skip over any default trait items that are impossible to reference
20141995 // (e.g. if it has a `Self: Sized` bound on an unsized type).
@@ -2028,8 +2009,8 @@ fn render_impl(
20282009 let assoc_link = AssocItemLink :: GotoSource ( did. into ( ) , & provided_methods) ;
20292010
20302011 doc_impl_item (
2031- boring,
2032- interesting,
2012+ & mut boring,
2013+ & mut interesting,
20332014 cx,
20342015 trait_item,
20352016 parent,
@@ -2038,8 +2019,9 @@ fn render_impl(
20382019 true ,
20392020 Some ( t) ,
20402021 rendering_params,
2041- ) ;
2022+ ) ? ;
20422023 }
2024+ Ok ( ( ) )
20432025 }
20442026
20452027 // If we've implemented a trait, then also emit documentation for all
@@ -2059,7 +2041,7 @@ fn render_impl(
20592041 & i. impl_item ,
20602042 render_mode,
20612043 rendering_params,
2062- ) ;
2044+ ) ? ;
20632045 }
20642046 }
20652047 if render_mode == RenderMode :: Normal {
0 commit comments