@@ -47,6 +47,7 @@ use std::path::PathBuf;
4747use std:: { fs, str} ;
4848
4949use askama:: Template ;
50+ use itertools:: Either ;
5051use rustc_attr_parsing:: {
5152 ConstStability , DeprecatedSince , Deprecation , RustcVersion , StabilityLevel , StableSince ,
5253} ;
@@ -1644,8 +1645,8 @@ fn render_impl(
16441645 // `containing_item` is used for rendering stability info. If the parent is a trait impl,
16451646 // `containing_item` will the grandparent, since trait impls can't have stability attached.
16461647 fn doc_impl_item (
1647- boring : & mut String ,
1648- interesting : & mut String ,
1648+ boring : impl fmt :: Write ,
1649+ interesting : impl fmt :: Write ,
16491650 cx : & Context < ' _ > ,
16501651 item : & clean:: Item ,
16511652 parent : & clean:: Item ,
@@ -1654,7 +1655,7 @@ fn render_impl(
16541655 is_default_item : bool ,
16551656 trait_ : Option < & clean:: Trait > ,
16561657 rendering_params : ImplRenderingParameters ,
1657- ) {
1658+ ) -> fmt :: Result {
16581659 let item_type = item. type_ ( ) ;
16591660 let name = item. name . as_ref ( ) . unwrap ( ) ;
16601661
@@ -1729,15 +1730,16 @@ fn render_impl(
17291730 ) ;
17301731 }
17311732 }
1732- let w = if short_documented && trait_. is_some ( ) { interesting } else { boring } ;
1733+ let mut w = if short_documented && trait_. is_some ( ) {
1734+ Either :: Left ( interesting)
1735+ } else {
1736+ Either :: Right ( boring)
1737+ } ;
17331738
17341739 let toggled = !doc_buffer. is_empty ( ) ;
17351740 if toggled {
17361741 let method_toggle_class = if item_type. is_method ( ) { " method-toggle" } else { "" } ;
1737- write_str (
1738- w,
1739- format_args ! ( "<details class=\" toggle{method_toggle_class}\" open><summary>" ) ,
1740- ) ;
1742+ write ! ( w, "<details class=\" toggle{method_toggle_class}\" open><summary>" ) ?;
17411743 }
17421744 match & item. kind {
17431745 clean:: MethodItem ( ..) | clean:: RequiredMethodItem ( _) => {
@@ -1752,172 +1754,151 @@ fn render_impl(
17521754 . find ( |item| item. name . map ( |n| n == * name) . unwrap_or ( false ) )
17531755 } )
17541756 . map ( |item| format ! ( "{}.{name}" , item. type_( ) ) ) ;
1755- write_str (
1757+ write ! (
17561758 w,
1757- format_args ! (
1758- "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
1759+ "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
17591760 {}",
1760- render_rightside( cx, item, render_mode)
1761- ) ,
1762- ) ;
1761+ render_rightside( cx, item, render_mode)
1762+ ) ?;
17631763 if trait_. is_some ( ) {
17641764 // Anchors are only used on trait impls.
1765- write_str ( w, format_args ! ( "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ) ;
1765+ write ! ( w, "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ? ;
17661766 }
1767- write_str (
1767+ write ! (
17681768 w,
1769- format_args ! (
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,
1777- ) ,
1769+ "<h4 class=\" code-header\" >{}</h4></section>" ,
1770+ render_assoc_item(
1771+ item,
1772+ link. anchor( source_id. as_ref( ) . unwrap_or( & id) ) ,
1773+ ItemType :: Impl ,
1774+ cx,
1775+ render_mode,
17781776 ) ,
1779- ) ;
1777+ ) ? ;
17801778 }
17811779 }
17821780 clean:: RequiredAssocConstItem ( generics, ty) => {
17831781 let source_id = format ! ( "{item_type}.{name}" ) ;
17841782 let id = cx. derive_id ( & source_id) ;
1785- write_str (
1783+ write ! (
17861784 w,
1787- format_args ! (
1788- "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
1785+ "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
17891786 {}",
1790- render_rightside( cx, item, render_mode)
1791- ) ,
1792- ) ;
1787+ render_rightside( cx, item, render_mode)
1788+ ) ?;
17931789 if trait_. is_some ( ) {
17941790 // Anchors are only used on trait impls.
1795- write_str ( w, format_args ! ( "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ) ;
1791+ write ! ( w, "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ? ;
17961792 }
1797- write_str (
1793+ write ! (
17981794 w,
1799- format_args ! (
1800- "<h4 class=\" code-header\" >{}</h4></section>" ,
1801- assoc_const(
1802- item,
1803- generics,
1804- ty,
1805- AssocConstValue :: None ,
1806- link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1807- 0 ,
1808- cx,
1809- )
1795+ "<h4 class=\" code-header\" >{}</h4></section>" ,
1796+ assoc_const(
1797+ item,
1798+ generics,
1799+ ty,
1800+ AssocConstValue :: None ,
1801+ link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1802+ 0 ,
1803+ cx,
18101804 ) ,
1811- ) ;
1805+ ) ? ;
18121806 }
18131807 clean:: ProvidedAssocConstItem ( ci) | clean:: ImplAssocConstItem ( ci) => {
18141808 let source_id = format ! ( "{item_type}.{name}" ) ;
18151809 let id = cx. derive_id ( & source_id) ;
1816- write_str (
1810+ write ! (
18171811 w,
1818- format_args ! (
1819- "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
1812+ "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
18201813 {}",
1821- render_rightside( cx, item, render_mode)
1822- ) ,
1823- ) ;
1814+ render_rightside( cx, item, render_mode) ,
1815+ ) ?;
18241816 if trait_. is_some ( ) {
18251817 // Anchors are only used on trait impls.
1826- write_str ( w, format_args ! ( "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ) ;
1818+ write ! ( w, "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ? ;
18271819 }
1828- write_str (
1820+ write ! (
18291821 w,
1830- format_args ! (
1831- "<h4 class=\" code-header\" >{}</h4></section>" ,
1832- assoc_const(
1833- item,
1834- & ci. generics,
1835- & ci. type_,
1836- match item. kind {
1837- clean:: ProvidedAssocConstItem ( _) =>
1838- AssocConstValue :: TraitDefault ( & ci. kind) ,
1839- clean:: ImplAssocConstItem ( _) => AssocConstValue :: Impl ( & ci. kind) ,
1840- _ => unreachable!( ) ,
1841- } ,
1842- link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1843- 0 ,
1844- cx,
1845- )
1822+ "<h4 class=\" code-header\" >{}</h4></section>" ,
1823+ assoc_const(
1824+ item,
1825+ & ci. generics,
1826+ & ci. type_,
1827+ match item. kind {
1828+ clean:: ProvidedAssocConstItem ( _) =>
1829+ AssocConstValue :: TraitDefault ( & ci. kind) ,
1830+ clean:: ImplAssocConstItem ( _) => AssocConstValue :: Impl ( & ci. kind) ,
1831+ _ => unreachable!( ) ,
1832+ } ,
1833+ link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1834+ 0 ,
1835+ cx,
18461836 ) ,
1847- ) ;
1837+ ) ? ;
18481838 }
18491839 clean:: RequiredAssocTypeItem ( generics, bounds) => {
18501840 let source_id = format ! ( "{item_type}.{name}" ) ;
18511841 let id = cx. derive_id ( & source_id) ;
1852- write_str (
1842+ write ! (
18531843 w,
1854- format_args ! (
1855- "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
1844+ "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
18561845 {}",
1857- render_rightside( cx, item, render_mode)
1858- ) ,
1859- ) ;
1846+ render_rightside( cx, item, render_mode) ,
1847+ ) ?;
18601848 if trait_. is_some ( ) {
18611849 // Anchors are only used on trait impls.
1862- write_str ( w, format_args ! ( "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ) ;
1850+ write ! ( w, "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ? ;
18631851 }
1864- write_str (
1852+ write ! (
18651853 w,
1866- format_args ! (
1867- "<h4 class=\" code-header\" >{}</h4></section>" ,
1868- assoc_type(
1869- item,
1870- generics,
1871- bounds,
1872- None ,
1873- link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1874- 0 ,
1875- cx,
1876- )
1854+ "<h4 class=\" code-header\" >{}</h4></section>" ,
1855+ assoc_type(
1856+ item,
1857+ generics,
1858+ bounds,
1859+ None ,
1860+ link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1861+ 0 ,
1862+ cx,
18771863 ) ,
1878- ) ;
1864+ ) ? ;
18791865 }
18801866 clean:: AssocTypeItem ( tydef, _bounds) => {
18811867 let source_id = format ! ( "{item_type}.{name}" ) ;
18821868 let id = cx. derive_id ( & source_id) ;
1883- write_str (
1869+ write ! (
18841870 w,
1885- format_args ! (
1886- "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
1871+ "<section id=\" {id}\" class=\" {item_type}{in_trait_class}\" >\
18871872 {}",
1888- render_rightside( cx, item, render_mode)
1889- ) ,
1890- ) ;
1873+ render_rightside( cx, item, render_mode) ,
1874+ ) ?;
18911875 if trait_. is_some ( ) {
18921876 // Anchors are only used on trait impls.
1893- write_str ( w, format_args ! ( "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ) ;
1877+ write ! ( w, "<a href=\" #{id}\" class=\" anchor\" >§</a>" ) ? ;
18941878 }
1895- write_str (
1879+ write ! (
18961880 w,
1897- format_args ! (
1898- "<h4 class=\" code-header\" >{}</h4></section>" ,
1899- assoc_type(
1900- item,
1901- & tydef. generics,
1902- & [ ] , // intentionally leaving out bounds
1903- Some ( tydef. item_type. as_ref( ) . unwrap_or( & tydef. type_) ) ,
1904- link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1905- 0 ,
1906- cx,
1907- )
1881+ "<h4 class=\" code-header\" >{}</h4></section>" ,
1882+ assoc_type(
1883+ item,
1884+ & tydef. generics,
1885+ & [ ] , // intentionally leaving out bounds
1886+ Some ( tydef. item_type. as_ref( ) . unwrap_or( & tydef. type_) ) ,
1887+ link. anchor( if trait_. is_some( ) { & source_id } else { & id } ) ,
1888+ 0 ,
1889+ cx,
19081890 ) ,
1909- ) ;
1891+ ) ? ;
19101892 }
1911- clean:: StrippedItem ( ..) => return ,
1893+ clean:: StrippedItem ( ..) => return Ok ( ( ) ) ,
19121894 _ => panic ! ( "can't make docs for trait item with name {:?}" , item. name) ,
19131895 }
19141896
1915- w. push_str ( & info_buffer) ;
1897+ w. write_str ( & info_buffer) ? ;
19161898 if toggled {
1917- w. push_str ( "</summary>" ) ;
1918- w. push_str ( & doc_buffer) ;
1919- w. push_str ( "</details>" ) ;
1899+ write ! ( w, "</summary>{doc_buffer}</details>" ) ?;
19201900 }
1901+ Ok ( ( ) )
19211902 }
19221903
19231904 let mut impl_items = String :: new ( ) ;
@@ -1960,7 +1941,7 @@ fn render_impl(
19601941 false ,
19611942 trait_,
19621943 rendering_params,
1963- ) ;
1944+ ) ? ;
19641945 }
19651946 _ => { }
19661947 }
@@ -1978,7 +1959,7 @@ fn render_impl(
19781959 false ,
19791960 trait_,
19801961 rendering_params,
1981- ) ;
1962+ ) ? ;
19821963 }
19831964 for method in methods {
19841965 doc_impl_item (
@@ -1992,20 +1973,20 @@ fn render_impl(
19921973 false ,
19931974 trait_,
19941975 rendering_params,
1995- ) ;
1976+ ) ? ;
19961977 }
19971978 }
19981979
19991980 fn render_default_items (
2000- boring : & mut String ,
2001- interesting : & mut String ,
1981+ mut boring : impl fmt :: Write ,
1982+ mut interesting : impl fmt :: Write ,
20021983 cx : & Context < ' _ > ,
20031984 t : & clean:: Trait ,
20041985 i : & clean:: Impl ,
20051986 parent : & clean:: Item ,
20061987 render_mode : RenderMode ,
20071988 rendering_params : ImplRenderingParameters ,
2008- ) {
1989+ ) -> fmt :: Result {
20091990 for trait_item in & t. items {
20101991 // Skip over any default trait items that are impossible to reference
20111992 // (e.g. if it has a `Self: Sized` bound on an unsized type).
@@ -2025,8 +2006,8 @@ fn render_impl(
20252006 let assoc_link = AssocItemLink :: GotoSource ( did. into ( ) , & provided_methods) ;
20262007
20272008 doc_impl_item (
2028- boring,
2029- interesting,
2009+ & mut boring,
2010+ & mut interesting,
20302011 cx,
20312012 trait_item,
20322013 parent,
@@ -2035,8 +2016,9 @@ fn render_impl(
20352016 true ,
20362017 Some ( t) ,
20372018 rendering_params,
2038- ) ;
2019+ ) ? ;
20392020 }
2021+ Ok ( ( ) )
20402022 }
20412023
20422024 // If we've implemented a trait, then also emit documentation for all
@@ -2056,7 +2038,7 @@ fn render_impl(
20562038 & i. impl_item ,
20572039 render_mode,
20582040 rendering_params,
2059- ) ;
2041+ ) ? ;
20602042 }
20612043 }
20622044 if render_mode == RenderMode :: Normal {
0 commit comments