@@ -115,6 +115,9 @@ crate struct Context<'tcx> {
115
115
crate render_redirect_pages : bool ,
116
116
/// The map used to ensure all generated 'id=' attributes are unique.
117
117
id_map : Rc < RefCell < IdMap > > ,
118
+ /// Tracks section IDs for `Deref` targets so they match in both the main
119
+ /// body and the sidebar.
120
+ deref_id_map : Rc < RefCell < FxHashMap < DefId , String > > > ,
118
121
crate shared : Arc < SharedContext < ' tcx > > ,
119
122
all : Rc < RefCell < AllTypes > > ,
120
123
/// Storage for the errors produced while generating documentation so they
@@ -372,7 +375,6 @@ crate fn initial_ids() -> Vec<String> {
372
375
"implementors-list" ,
373
376
"synthetic-implementors-list" ,
374
377
"methods" ,
375
- "deref-methods" ,
376
378
"implementations" ,
377
379
]
378
380
. iter ( )
@@ -506,6 +508,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
506
508
dst,
507
509
render_redirect_pages : false ,
508
510
id_map : Rc :: new ( RefCell :: new ( id_map) ) ,
511
+ deref_id_map : Rc :: new ( RefCell :: new ( FxHashMap :: default ( ) ) ) ,
509
512
shared : Arc :: new ( scx) ,
510
513
all : Rc :: new ( RefCell :: new ( AllTypes :: new ( ) ) ) ,
511
514
errors : Rc :: new ( receiver) ,
@@ -3517,14 +3520,18 @@ fn render_assoc_items(
3517
3520
RenderMode :: Normal
3518
3521
}
3519
3522
AssocItemRender :: DerefFor { trait_, type_, deref_mut_ } => {
3523
+ let id =
3524
+ cx. derive_id ( small_url_encode ( & format ! ( "deref-methods-{:#}" , type_. print( ) ) ) ) ;
3525
+ cx. deref_id_map . borrow_mut ( ) . insert ( type_. def_id ( ) . unwrap ( ) , id. clone ( ) ) ;
3520
3526
write ! (
3521
3527
w,
3522
- "<h2 id=\" deref-methods \" class=\" small-section-header\" >\
3523
- Methods from {}<Target = {}>\
3524
- <a href=\" #deref-methods \" class=\" anchor\" ></a>\
3528
+ "<h2 id=\" {id} \" class=\" small-section-header\" >\
3529
+ Methods from {trait_ }<Target = {type_ }>\
3530
+ <a href=\" #{id} \" class=\" anchor\" ></a>\
3525
3531
</h2>",
3526
- trait_. print( ) ,
3527
- type_. print( )
3532
+ id = id,
3533
+ trait_ = trait_. print( ) ,
3534
+ type_ = type_. print( ) ,
3528
3535
) ;
3529
3536
RenderMode :: ForDeref { mut_ : deref_mut_ }
3530
3537
}
@@ -4175,14 +4182,14 @@ fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer, cache:
4175
4182
) ;
4176
4183
}
4177
4184
match * it. kind {
4178
- clean:: StructItem ( ref s) => sidebar_struct ( buffer, it, s) ,
4179
- clean:: TraitItem ( ref t) => sidebar_trait ( buffer, it, t) ,
4180
- clean:: PrimitiveItem ( _) => sidebar_primitive ( buffer, it) ,
4181
- clean:: UnionItem ( ref u) => sidebar_union ( buffer, it, u) ,
4182
- clean:: EnumItem ( ref e) => sidebar_enum ( buffer, it, e) ,
4183
- clean:: TypedefItem ( _, _) => sidebar_typedef ( buffer, it) ,
4185
+ clean:: StructItem ( ref s) => sidebar_struct ( cx , buffer, it, s) ,
4186
+ clean:: TraitItem ( ref t) => sidebar_trait ( cx , buffer, it, t) ,
4187
+ clean:: PrimitiveItem ( _) => sidebar_primitive ( cx , buffer, it) ,
4188
+ clean:: UnionItem ( ref u) => sidebar_union ( cx , buffer, it, u) ,
4189
+ clean:: EnumItem ( ref e) => sidebar_enum ( cx , buffer, it, e) ,
4190
+ clean:: TypedefItem ( _, _) => sidebar_typedef ( cx , buffer, it) ,
4184
4191
clean:: ModuleItem ( ref m) => sidebar_module ( buffer, & m. items ) ,
4185
- clean:: ForeignTypeItem => sidebar_foreign_type ( buffer, it) ,
4192
+ clean:: ForeignTypeItem => sidebar_foreign_type ( cx , buffer, it) ,
4186
4193
_ => ( ) ,
4187
4194
}
4188
4195
@@ -4283,7 +4290,7 @@ fn small_url_encode(s: &str) -> String {
4283
4290
. replace ( "\" " , "%22" )
4284
4291
}
4285
4292
4286
- fn sidebar_assoc_items ( it : & clean:: Item ) -> String {
4293
+ fn sidebar_assoc_items ( cx : & Context < ' _ > , it : & clean:: Item ) -> String {
4287
4294
let mut out = String :: new ( ) ;
4288
4295
let c = cache ( ) ;
4289
4296
if let Some ( v) = c. impls . get ( & it. def_id ) {
@@ -4313,7 +4320,7 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
4313
4320
. filter ( |i| i. inner_impl ( ) . trait_ . is_some ( ) )
4314
4321
. find ( |i| i. inner_impl ( ) . trait_ . def_id ( ) == c. deref_trait_did )
4315
4322
{
4316
- out. push_str ( & sidebar_deref_methods ( impl_, v) ) ;
4323
+ out. push_str ( & sidebar_deref_methods ( cx , impl_, v) ) ;
4317
4324
}
4318
4325
let format_impls = |impls : Vec < & Impl > | {
4319
4326
let mut links = FxHashSet :: default ( ) ;
@@ -4381,7 +4388,7 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
4381
4388
out
4382
4389
}
4383
4390
4384
- fn sidebar_deref_methods ( impl_ : & Impl , v : & Vec < Impl > ) -> String {
4391
+ fn sidebar_deref_methods ( cx : & Context < ' _ > , impl_ : & Impl , v : & Vec < Impl > ) -> String {
4385
4392
let mut out = String :: new ( ) ;
4386
4393
let c = cache ( ) ;
4387
4394
@@ -4408,22 +4415,26 @@ fn sidebar_deref_methods(impl_: &Impl, v: &Vec<Impl>) -> String {
4408
4415
. and_then ( |did| c. impls . get ( & did) ) ;
4409
4416
if let Some ( impls) = inner_impl {
4410
4417
debug ! ( "found inner_impl: {:?}" , impls) ;
4411
- out. push_str ( "<a class=\" sidebar-title\" href=\" #deref-methods\" >" ) ;
4412
- out. push_str ( & format ! (
4413
- "Methods from {}<Target={}>" ,
4414
- Escape ( & format!( "{:#}" , impl_. inner_impl( ) . trait_. as_ref( ) . unwrap( ) . print( ) ) ) ,
4415
- Escape ( & format!( "{:#}" , real_target. print( ) ) )
4416
- ) ) ;
4417
- out. push_str ( "</a>" ) ;
4418
4418
let mut used_links = FxHashSet :: default ( ) ;
4419
4419
let mut ret = impls
4420
4420
. iter ( )
4421
4421
. filter ( |i| i. inner_impl ( ) . trait_ . is_none ( ) )
4422
4422
. flat_map ( |i| get_methods ( i. inner_impl ( ) , true , & mut used_links, deref_mut) )
4423
4423
. collect :: < Vec < _ > > ( ) ;
4424
- // We want links' order to be reproducible so we don't use unstable sort.
4425
- ret. sort ( ) ;
4426
4424
if !ret. is_empty ( ) {
4425
+ let deref_id_map = cx. deref_id_map . borrow ( ) ;
4426
+ let id = deref_id_map
4427
+ . get ( & real_target. def_id ( ) . unwrap ( ) )
4428
+ . expect ( "Deref section without derived id" ) ;
4429
+ out. push_str ( & format ! ( "<a class=\" sidebar-title\" href=\" #{}\" >" , id) ) ;
4430
+ out. push_str ( & format ! (
4431
+ "Methods from {}<Target={}>" ,
4432
+ Escape ( & format!( "{:#}" , impl_. inner_impl( ) . trait_. as_ref( ) . unwrap( ) . print( ) ) ) ,
4433
+ Escape ( & format!( "{:#}" , real_target. print( ) ) )
4434
+ ) ) ;
4435
+ out. push_str ( "</a>" ) ;
4436
+ // We want links' order to be reproducible so we don't use unstable sort.
4437
+ ret. sort ( ) ;
4427
4438
out. push_str ( & format ! ( "<div class=\" sidebar-links\" >{}</div>" , ret. join( "" ) ) ) ;
4428
4439
}
4429
4440
}
@@ -4443,7 +4454,7 @@ fn sidebar_deref_methods(impl_: &Impl, v: &Vec<Impl>) -> String {
4443
4454
return out;
4444
4455
}
4445
4456
}
4446
- out. push_str ( & sidebar_deref_methods ( target_deref_impl, target_impls) ) ;
4457
+ out. push_str ( & sidebar_deref_methods ( cx , target_deref_impl, target_impls) ) ;
4447
4458
}
4448
4459
}
4449
4460
}
@@ -4452,7 +4463,7 @@ fn sidebar_deref_methods(impl_: &Impl, v: &Vec<Impl>) -> String {
4452
4463
out
4453
4464
}
4454
4465
4455
- fn sidebar_struct ( buf : & mut Buffer , it : & clean:: Item , s : & clean:: Struct ) {
4466
+ fn sidebar_struct ( cx : & Context < ' _ > , buf : & mut Buffer , it : & clean:: Item , s : & clean:: Struct ) {
4456
4467
let mut sidebar = String :: new ( ) ;
4457
4468
let fields = get_struct_fields_name ( & s. fields ) ;
4458
4469
@@ -4466,7 +4477,7 @@ fn sidebar_struct(buf: &mut Buffer, it: &clean::Item, s: &clean::Struct) {
4466
4477
}
4467
4478
}
4468
4479
4469
- sidebar. push_str ( & sidebar_assoc_items ( it) ) ;
4480
+ sidebar. push_str ( & sidebar_assoc_items ( cx , it) ) ;
4470
4481
4471
4482
if !sidebar. is_empty ( ) {
4472
4483
write ! ( buf, "<div class=\" block items\" >{}</div>" , sidebar) ;
@@ -4497,7 +4508,7 @@ fn is_negative_impl(i: &clean::Impl) -> bool {
4497
4508
i. polarity == Some ( clean:: ImplPolarity :: Negative )
4498
4509
}
4499
4510
4500
- fn sidebar_trait ( buf : & mut Buffer , it : & clean:: Item , t : & clean:: Trait ) {
4511
+ fn sidebar_trait ( cx : & Context < ' _ > , buf : & mut Buffer , it : & clean:: Item , t : & clean:: Trait ) {
4501
4512
let mut sidebar = String :: new ( ) ;
4502
4513
4503
4514
let mut types = t
@@ -4597,7 +4608,7 @@ fn sidebar_trait(buf: &mut Buffer, it: &clean::Item, t: &clean::Trait) {
4597
4608
}
4598
4609
}
4599
4610
4600
- sidebar. push_str ( & sidebar_assoc_items ( it) ) ;
4611
+ sidebar. push_str ( & sidebar_assoc_items ( cx , it) ) ;
4601
4612
4602
4613
sidebar. push_str ( "<a class=\" sidebar-title\" href=\" #implementors\" >Implementors</a>" ) ;
4603
4614
if t. is_auto {
@@ -4610,16 +4621,16 @@ fn sidebar_trait(buf: &mut Buffer, it: &clean::Item, t: &clean::Trait) {
4610
4621
write ! ( buf, "<div class=\" block items\" >{}</div>" , sidebar)
4611
4622
}
4612
4623
4613
- fn sidebar_primitive ( buf : & mut Buffer , it : & clean:: Item ) {
4614
- let sidebar = sidebar_assoc_items ( it) ;
4624
+ fn sidebar_primitive ( cx : & Context < ' _ > , buf : & mut Buffer , it : & clean:: Item ) {
4625
+ let sidebar = sidebar_assoc_items ( cx , it) ;
4615
4626
4616
4627
if !sidebar. is_empty ( ) {
4617
4628
write ! ( buf, "<div class=\" block items\" >{}</div>" , sidebar) ;
4618
4629
}
4619
4630
}
4620
4631
4621
- fn sidebar_typedef ( buf : & mut Buffer , it : & clean:: Item ) {
4622
- let sidebar = sidebar_assoc_items ( it) ;
4632
+ fn sidebar_typedef ( cx : & Context < ' _ > , buf : & mut Buffer , it : & clean:: Item ) {
4633
+ let sidebar = sidebar_assoc_items ( cx , it) ;
4623
4634
4624
4635
if !sidebar. is_empty ( ) {
4625
4636
write ! ( buf, "<div class=\" block items\" >{}</div>" , sidebar) ;
@@ -4641,7 +4652,7 @@ fn get_struct_fields_name(fields: &[clean::Item]) -> String {
4641
4652
fields. join ( "" )
4642
4653
}
4643
4654
4644
- fn sidebar_union ( buf : & mut Buffer , it : & clean:: Item , u : & clean:: Union ) {
4655
+ fn sidebar_union ( cx : & Context < ' _ > , buf : & mut Buffer , it : & clean:: Item , u : & clean:: Union ) {
4645
4656
let mut sidebar = String :: new ( ) ;
4646
4657
let fields = get_struct_fields_name ( & u. fields ) ;
4647
4658
@@ -4653,14 +4664,14 @@ fn sidebar_union(buf: &mut Buffer, it: &clean::Item, u: &clean::Union) {
4653
4664
) ) ;
4654
4665
}
4655
4666
4656
- sidebar. push_str ( & sidebar_assoc_items ( it) ) ;
4667
+ sidebar. push_str ( & sidebar_assoc_items ( cx , it) ) ;
4657
4668
4658
4669
if !sidebar. is_empty ( ) {
4659
4670
write ! ( buf, "<div class=\" block items\" >{}</div>" , sidebar) ;
4660
4671
}
4661
4672
}
4662
4673
4663
- fn sidebar_enum ( buf : & mut Buffer , it : & clean:: Item , e : & clean:: Enum ) {
4674
+ fn sidebar_enum ( cx : & Context < ' _ > , buf : & mut Buffer , it : & clean:: Item , e : & clean:: Enum ) {
4664
4675
let mut sidebar = String :: new ( ) ;
4665
4676
4666
4677
let mut variants = e
@@ -4680,7 +4691,7 @@ fn sidebar_enum(buf: &mut Buffer, it: &clean::Item, e: &clean::Enum) {
4680
4691
) ) ;
4681
4692
}
4682
4693
4683
- sidebar. push_str ( & sidebar_assoc_items ( it) ) ;
4694
+ sidebar. push_str ( & sidebar_assoc_items ( cx , it) ) ;
4684
4695
4685
4696
if !sidebar. is_empty ( ) {
4686
4697
write ! ( buf, "<div class=\" block items\" >{}</div>" , sidebar) ;
@@ -4769,8 +4780,8 @@ fn sidebar_module(buf: &mut Buffer, items: &[clean::Item]) {
4769
4780
}
4770
4781
}
4771
4782
4772
- fn sidebar_foreign_type ( buf : & mut Buffer , it : & clean:: Item ) {
4773
- let sidebar = sidebar_assoc_items ( it) ;
4783
+ fn sidebar_foreign_type ( cx : & Context < ' _ > , buf : & mut Buffer , it : & clean:: Item ) {
4784
+ let sidebar = sidebar_assoc_items ( cx , it) ;
4774
4785
if !sidebar. is_empty ( ) {
4775
4786
write ! ( buf, "<div class=\" block items\" >{}</div>" , sidebar) ;
4776
4787
}
0 commit comments