@@ -613,10 +613,10 @@ fn short_item_info(
613
613
614
614
// Render the list of items inside one of the sections "Trait Implementations",
615
615
// "Auto Trait Implementations," "Blanket Trait Implementations" (on struct/enum pages).
616
- fn render_impls (
616
+ pub ( crate ) fn render_impls (
617
617
cx : & mut Context < ' _ > ,
618
618
w : & mut Buffer ,
619
- impls : & [ & & Impl ] ,
619
+ impls : & [ & Impl ] ,
620
620
containing_item : & clean:: Item ,
621
621
toggle_open_by_default : bool ,
622
622
) {
@@ -1025,6 +1025,47 @@ impl<'a> AssocItemLink<'a> {
1025
1025
}
1026
1026
}
1027
1027
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
+
1028
1069
fn render_assoc_items (
1029
1070
w : & mut Buffer ,
1030
1071
cx : & mut Context < ' _ > ,
@@ -1054,12 +1095,7 @@ fn render_assoc_items_inner(
1054
1095
let mut tmp_buf = Buffer :: empty_from ( w) ;
1055
1096
let ( render_mode, id) = match what {
1056
1097
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" ) ;
1063
1099
( RenderMode :: Normal , "implementations-list" . to_owned ( ) )
1064
1100
}
1065
1101
AssocItemRender :: DerefFor { trait_, type_, deref_mut_ } => {
@@ -1068,15 +1104,14 @@ fn render_assoc_items_inner(
1068
1104
if let Some ( def_id) = type_. def_id ( cx. cache ( ) ) {
1069
1105
cx. deref_id_map . insert ( def_id, id. clone ( ) ) ;
1070
1106
}
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,
1080
1115
) ;
1081
1116
( RenderMode :: ForDeref { mut_ : deref_mut_ } , cx. derive_id ( id) )
1082
1117
}
@@ -1123,49 +1158,12 @@ fn render_assoc_items_inner(
1123
1158
return ;
1124
1159
}
1125
1160
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 > , _ ) =
1129
1164
concrete. into_iter ( ) . partition ( |t| t. inner_impl ( ) . kind . is_blanket ( ) ) ;
1130
1165
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) ;
1169
1167
}
1170
1168
}
1171
1169
@@ -1970,6 +1968,70 @@ fn small_url_encode(s: String) -> String {
1970
1968
}
1971
1969
}
1972
1970
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
+
1973
2035
fn sidebar_assoc_items ( cx : & Context < ' _ > , out : & mut Buffer , it : & clean:: Item ) {
1974
2036
let did = it. item_id . expect_def_id ( ) ;
1975
2037
let cache = cx. cache ( ) ;
@@ -2018,65 +2080,12 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
2018
2080
sidebar_deref_methods ( cx, out, impl_, v, & mut derefs, & mut used_links) ;
2019
2081
}
2020
2082
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
-
2045
2083
let ( synthetic, concrete) : ( Vec < & Impl > , Vec < & Impl > ) =
2046
2084
v. iter ( ) . partition :: < Vec < _ > , _ > ( |i| i. inner_impl ( ) . kind . is_auto ( ) ) ;
2047
2085
let ( blanket_impl, concrete) : ( Vec < & Impl > , Vec < & Impl > ) =
2048
2086
concrete. into_iter ( ) . partition :: < Vec < _ > , _ > ( |i| i. inner_impl ( ) . kind . is_blanket ( ) ) ;
2049
2087
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) ;
2080
2089
}
2081
2090
}
2082
2091
}
@@ -2346,9 +2355,54 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean
2346
2355
buf. push_str ( "</section>" )
2347
2356
}
2348
2357
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
+
2349
2388
fn sidebar_primitive ( cx : & Context < ' _ > , buf : & mut Buffer , it : & clean:: Item ) {
2350
2389
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
+ }
2352
2406
2353
2407
if !sidebar. is_empty ( ) {
2354
2408
write ! ( buf, "<section>{}</section>" , sidebar. into_inner( ) ) ;
0 commit comments