@@ -613,10 +613,10 @@ fn short_item_info(
613613
614614// Render the list of items inside one of the sections "Trait Implementations",
615615// "Auto Trait Implementations," "Blanket Trait Implementations" (on struct/enum pages).
616- fn render_impls (
616+ pub ( crate ) fn render_impls (
617617 cx : & mut Context < ' _ > ,
618618 w : & mut Buffer ,
619- impls : & [ & & Impl ] ,
619+ impls : & [ & Impl ] ,
620620 containing_item : & clean:: Item ,
621621 toggle_open_by_default : bool ,
622622) {
@@ -1025,6 +1025,47 @@ impl<'a> AssocItemLink<'a> {
10251025 }
10261026}
10271027
1028+ fn write_impl_section_heading ( w : & mut Buffer , title : & str , id : & str ) {
1029+ write ! (
1030+ w,
1031+ "<h2 id=\" {id}\" class=\" small-section-header\" >\
1032+ {title}\
1033+ <a href=\" #{id}\" class=\" anchor\" ></a>\
1034+ </h2>"
1035+ ) ;
1036+ }
1037+
1038+ pub ( crate ) fn render_all_impls (
1039+ w : & mut Buffer ,
1040+ cx : & mut Context < ' _ > ,
1041+ containing_item : & clean:: Item ,
1042+ concrete : & [ & Impl ] ,
1043+ synthetic : & [ & Impl ] ,
1044+ blanket_impl : & [ & Impl ] ,
1045+ ) {
1046+ let mut impls = Buffer :: empty_from ( w) ;
1047+ render_impls ( cx, & mut impls, concrete, containing_item, true ) ;
1048+ let impls = impls. into_inner ( ) ;
1049+ if !impls. is_empty ( ) {
1050+ write_impl_section_heading ( w, "Trait Implementations" , "trait-implementations" ) ;
1051+ write ! ( w, "<div id=\" trait-implementations-list\" >{}</div>" , impls) ;
1052+ }
1053+
1054+ if !synthetic. is_empty ( ) {
1055+ write_impl_section_heading ( w, "Auto Trait Implementations" , "synthetic-implementations" ) ;
1056+ w. write_str ( "<div id=\" synthetic-implementations-list\" >" ) ;
1057+ render_impls ( cx, w, synthetic, containing_item, false ) ;
1058+ w. write_str ( "</div>" ) ;
1059+ }
1060+
1061+ if !blanket_impl. is_empty ( ) {
1062+ write_impl_section_heading ( w, "Blanket Implementations" , "blanket-implementations" ) ;
1063+ w. write_str ( "<div id=\" blanket-implementations-list\" >" ) ;
1064+ render_impls ( cx, w, blanket_impl, containing_item, false ) ;
1065+ w. write_str ( "</div>" ) ;
1066+ }
1067+ }
1068+
10281069fn render_assoc_items (
10291070 w : & mut Buffer ,
10301071 cx : & mut Context < ' _ > ,
@@ -1054,12 +1095,7 @@ fn render_assoc_items_inner(
10541095 let mut tmp_buf = Buffer :: empty_from ( w) ;
10551096 let ( render_mode, id) = match what {
10561097 AssocItemRender :: All => {
1057- tmp_buf. write_str (
1058- "<h2 id=\" implementations\" class=\" small-section-header\" >\
1059- Implementations\
1060- <a href=\" #implementations\" class=\" anchor\" ></a>\
1061- </h2>",
1062- ) ;
1098+ write_impl_section_heading ( & mut tmp_buf, "Implementations" , "implementations" ) ;
10631099 ( RenderMode :: Normal , "implementations-list" . to_owned ( ) )
10641100 }
10651101 AssocItemRender :: DerefFor { trait_, type_, deref_mut_ } => {
@@ -1068,15 +1104,14 @@ fn render_assoc_items_inner(
10681104 if let Some ( def_id) = type_. def_id ( cx. cache ( ) ) {
10691105 cx. deref_id_map . insert ( def_id, id. clone ( ) ) ;
10701106 }
1071- write ! (
1072- tmp_buf,
1073- "<h2 id=\" {id}\" class=\" small-section-header\" >\
1074- <span>Methods from {trait_}<Target = {type_}></span>\
1075- <a href=\" #{id}\" class=\" anchor\" ></a>\
1076- </h2>",
1077- id = id,
1078- trait_ = trait_. print( cx) ,
1079- type_ = type_. print( cx) ,
1107+ write_impl_section_heading (
1108+ & mut tmp_buf,
1109+ & format ! (
1110+ "<span>Methods from {trait_}<Target = {type_}></span>" ,
1111+ trait_ = trait_. print( cx) ,
1112+ type_ = type_. print( cx) ,
1113+ ) ,
1114+ & id,
10801115 ) ;
10811116 ( RenderMode :: ForDeref { mut_ : deref_mut_ } , cx. derive_id ( id) )
10821117 }
@@ -1123,49 +1158,12 @@ fn render_assoc_items_inner(
11231158 return ;
11241159 }
11251160
1126- let ( synthetic, concrete) : ( Vec < & & Impl > , Vec < & & Impl > ) =
1127- traits. iter ( ) . partition ( |t| t. inner_impl ( ) . kind . is_auto ( ) ) ;
1128- let ( blanket_impl, concrete) : ( Vec < & & Impl > , _ ) =
1161+ let ( synthetic, concrete) : ( Vec < & Impl > , Vec < & Impl > ) =
1162+ traits. into_iter ( ) . partition ( |t| t. inner_impl ( ) . kind . is_auto ( ) ) ;
1163+ let ( blanket_impl, concrete) : ( Vec < & Impl > , _ ) =
11291164 concrete. into_iter ( ) . partition ( |t| t. inner_impl ( ) . kind . is_blanket ( ) ) ;
11301165
1131- let mut impls = Buffer :: empty_from ( w) ;
1132- render_impls ( cx, & mut impls, & concrete, containing_item, true ) ;
1133- let impls = impls. into_inner ( ) ;
1134- if !impls. is_empty ( ) {
1135- write ! (
1136- w,
1137- "<h2 id=\" trait-implementations\" class=\" small-section-header\" >\
1138- Trait Implementations\
1139- <a href=\" #trait-implementations\" class=\" anchor\" ></a>\
1140- </h2>\
1141- <div id=\" trait-implementations-list\" >{}</div>",
1142- impls
1143- ) ;
1144- }
1145-
1146- if !synthetic. is_empty ( ) {
1147- w. write_str (
1148- "<h2 id=\" synthetic-implementations\" class=\" small-section-header\" >\
1149- Auto Trait Implementations\
1150- <a href=\" #synthetic-implementations\" class=\" anchor\" ></a>\
1151- </h2>\
1152- <div id=\" synthetic-implementations-list\" >",
1153- ) ;
1154- render_impls ( cx, w, & synthetic, containing_item, false ) ;
1155- w. write_str ( "</div>" ) ;
1156- }
1157-
1158- if !blanket_impl. is_empty ( ) {
1159- w. write_str (
1160- "<h2 id=\" blanket-implementations\" class=\" small-section-header\" >\
1161- Blanket Implementations\
1162- <a href=\" #blanket-implementations\" class=\" anchor\" ></a>\
1163- </h2>\
1164- <div id=\" blanket-implementations-list\" >",
1165- ) ;
1166- render_impls ( cx, w, & blanket_impl, containing_item, false ) ;
1167- w. write_str ( "</div>" ) ;
1168- }
1166+ render_all_impls ( w, cx, containing_item, & concrete, & synthetic, & blanket_impl) ;
11691167 }
11701168}
11711169
@@ -1970,6 +1968,70 @@ fn small_url_encode(s: String) -> String {
19701968 }
19711969}
19721970
1971+ pub ( crate ) fn sidebar_render_assoc_items (
1972+ cx : & Context < ' _ > ,
1973+ out : & mut Buffer ,
1974+ id_map : & mut IdMap ,
1975+ concrete : Vec < & Impl > ,
1976+ synthetic : Vec < & Impl > ,
1977+ blanket_impl : Vec < & Impl > ,
1978+ ) {
1979+ let format_impls = |impls : Vec < & Impl > , id_map : & mut IdMap | {
1980+ let mut links = FxHashSet :: default ( ) ;
1981+
1982+ let mut ret = impls
1983+ . iter ( )
1984+ . filter_map ( |it| {
1985+ let trait_ = it. inner_impl ( ) . trait_ . as_ref ( ) ?;
1986+ let encoded =
1987+ id_map. derive ( get_id_for_impl ( & it. inner_impl ( ) . for_ , Some ( trait_) , cx) ) ;
1988+
1989+ let i_display = format ! ( "{:#}" , trait_. print( cx) ) ;
1990+ let out = Escape ( & i_display) ;
1991+ let prefix = match it. inner_impl ( ) . polarity {
1992+ ty:: ImplPolarity :: Positive | ty:: ImplPolarity :: Reservation => "" ,
1993+ ty:: ImplPolarity :: Negative => "!" ,
1994+ } ;
1995+ let generated = format ! ( "<a href=\" #{}\" >{}{}</a>" , encoded, prefix, out) ;
1996+ if links. insert ( generated. clone ( ) ) { Some ( generated) } else { None }
1997+ } )
1998+ . collect :: < Vec < String > > ( ) ;
1999+ ret. sort ( ) ;
2000+ ret
2001+ } ;
2002+
2003+ let concrete_format = format_impls ( concrete, id_map) ;
2004+ let synthetic_format = format_impls ( synthetic, id_map) ;
2005+ let blanket_format = format_impls ( blanket_impl, id_map) ;
2006+
2007+ if !concrete_format. is_empty ( ) {
2008+ print_sidebar_block (
2009+ out,
2010+ "trait-implementations" ,
2011+ "Trait Implementations" ,
2012+ concrete_format. iter ( ) ,
2013+ ) ;
2014+ }
2015+
2016+ if !synthetic_format. is_empty ( ) {
2017+ print_sidebar_block (
2018+ out,
2019+ "synthetic-implementations" ,
2020+ "Auto Trait Implementations" ,
2021+ synthetic_format. iter ( ) ,
2022+ ) ;
2023+ }
2024+
2025+ if !blanket_format. is_empty ( ) {
2026+ print_sidebar_block (
2027+ out,
2028+ "blanket-implementations" ,
2029+ "Blanket Implementations" ,
2030+ blanket_format. iter ( ) ,
2031+ ) ;
2032+ }
2033+ }
2034+
19732035fn sidebar_assoc_items ( cx : & Context < ' _ > , out : & mut Buffer , it : & clean:: Item ) {
19742036 let did = it. item_id . expect_def_id ( ) ;
19752037 let cache = cx. cache ( ) ;
@@ -2018,65 +2080,12 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
20182080 sidebar_deref_methods ( cx, out, impl_, v, & mut derefs, & mut used_links) ;
20192081 }
20202082
2021- let format_impls = |impls : Vec < & Impl > , id_map : & mut IdMap | {
2022- let mut links = FxHashSet :: default ( ) ;
2023-
2024- let mut ret = impls
2025- . iter ( )
2026- . filter_map ( |it| {
2027- let trait_ = it. inner_impl ( ) . trait_ . as_ref ( ) ?;
2028- let encoded =
2029- id_map. derive ( get_id_for_impl ( & it. inner_impl ( ) . for_ , Some ( trait_) , cx) ) ;
2030-
2031- let i_display = format ! ( "{:#}" , trait_. print( cx) ) ;
2032- let out = Escape ( & i_display) ;
2033- let prefix = match it. inner_impl ( ) . polarity {
2034- ty:: ImplPolarity :: Positive | ty:: ImplPolarity :: Reservation => "" ,
2035- ty:: ImplPolarity :: Negative => "!" ,
2036- } ;
2037- let generated = format ! ( "<a href=\" #{}\" >{}{}</a>" , encoded, prefix, out) ;
2038- if links. insert ( generated. clone ( ) ) { Some ( generated) } else { None }
2039- } )
2040- . collect :: < Vec < String > > ( ) ;
2041- ret. sort ( ) ;
2042- ret
2043- } ;
2044-
20452083 let ( synthetic, concrete) : ( Vec < & Impl > , Vec < & Impl > ) =
20462084 v. iter ( ) . partition :: < Vec < _ > , _ > ( |i| i. inner_impl ( ) . kind . is_auto ( ) ) ;
20472085 let ( blanket_impl, concrete) : ( Vec < & Impl > , Vec < & Impl > ) =
20482086 concrete. into_iter ( ) . partition :: < Vec < _ > , _ > ( |i| i. inner_impl ( ) . kind . is_blanket ( ) ) ;
20492087
2050- let concrete_format = format_impls ( concrete, & mut id_map) ;
2051- let synthetic_format = format_impls ( synthetic, & mut id_map) ;
2052- let blanket_format = format_impls ( blanket_impl, & mut id_map) ;
2053-
2054- if !concrete_format. is_empty ( ) {
2055- print_sidebar_block (
2056- out,
2057- "trait-implementations" ,
2058- "Trait Implementations" ,
2059- concrete_format. iter ( ) ,
2060- ) ;
2061- }
2062-
2063- if !synthetic_format. is_empty ( ) {
2064- print_sidebar_block (
2065- out,
2066- "synthetic-implementations" ,
2067- "Auto Trait Implementations" ,
2068- synthetic_format. iter ( ) ,
2069- ) ;
2070- }
2071-
2072- if !blanket_format. is_empty ( ) {
2073- print_sidebar_block (
2074- out,
2075- "blanket-implementations" ,
2076- "Blanket Implementations" ,
2077- blanket_format. iter ( ) ,
2078- ) ;
2079- }
2088+ sidebar_render_assoc_items ( cx, out, & mut id_map, concrete, synthetic, blanket_impl) ;
20802089 }
20812090 }
20822091}
@@ -2346,9 +2355,54 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean
23462355 buf. push_str ( "</section>" )
23472356}
23482357
2358+ /// Returns the list of implementations for the primitive reference type, filtering out any
2359+ /// implementations that are on concrete or partially generic types, only keeping implementations
2360+ /// of the form `impl<T> Trait for &T`.
2361+ pub ( crate ) fn get_filtered_impls_for_reference < ' a > (
2362+ shared : & ' a Rc < SharedContext < ' _ > > ,
2363+ it : & clean:: Item ,
2364+ ) -> ( Vec < & ' a Impl > , Vec < & ' a Impl > , Vec < & ' a Impl > ) {
2365+ let def_id = it. item_id . expect_def_id ( ) ;
2366+ // If the reference primitive is somehow not defined, exit early.
2367+ let Some ( v) = shared. cache . impls . get ( & def_id) else { return ( Vec :: new ( ) , Vec :: new ( ) , Vec :: new ( ) ) } ;
2368+ // Since there is no "direct implementation" on the reference primitive type, we filter out
2369+ // every implementation which isn't a trait implementation.
2370+ let traits: Vec < _ > = v. iter ( ) . filter ( |i| i. inner_impl ( ) . trait_ . is_some ( ) ) . collect ( ) ;
2371+ let ( synthetic, concrete) : ( Vec < & Impl > , Vec < & Impl > ) =
2372+ traits. into_iter ( ) . partition ( |t| t. inner_impl ( ) . kind . is_auto ( ) ) ;
2373+
2374+ let ( blanket_impl, concrete) : ( Vec < & Impl > , _ ) =
2375+ concrete. into_iter ( ) . partition ( |t| t. inner_impl ( ) . kind . is_blanket ( ) ) ;
2376+ // Now we keep only references over full generic types.
2377+ let concrete: Vec < _ > = concrete
2378+ . into_iter ( )
2379+ . filter ( |t| match t. inner_impl ( ) . for_ {
2380+ clean:: Type :: BorrowedRef { ref type_, .. } => type_. is_full_generic ( ) ,
2381+ _ => false ,
2382+ } )
2383+ . collect ( ) ;
2384+
2385+ ( concrete, synthetic, blanket_impl)
2386+ }
2387+
23492388fn sidebar_primitive ( cx : & Context < ' _ > , buf : & mut Buffer , it : & clean:: Item ) {
23502389 let mut sidebar = Buffer :: new ( ) ;
2351- sidebar_assoc_items ( cx, & mut sidebar, it) ;
2390+
2391+ if it. name . map ( |n| n. as_str ( ) != "reference" ) . unwrap_or ( false ) {
2392+ sidebar_assoc_items ( cx, & mut sidebar, it) ;
2393+ } else {
2394+ let shared = Rc :: clone ( & cx. shared ) ;
2395+ let ( concrete, synthetic, blanket_impl) = get_filtered_impls_for_reference ( & shared, it) ;
2396+
2397+ sidebar_render_assoc_items (
2398+ cx,
2399+ & mut sidebar,
2400+ & mut IdMap :: new ( ) ,
2401+ concrete,
2402+ synthetic,
2403+ blanket_impl,
2404+ ) ;
2405+ }
23522406
23532407 if !sidebar. is_empty ( ) {
23542408 write ! ( buf, "<section>{}</section>" , sidebar. into_inner( ) ) ;
0 commit comments