1- use std:: cell:: RefCell ;
1+ use std:: cell:: { RefCell , RefMut } ;
22use std:: collections:: BTreeMap ;
33use std:: error:: Error as StdError ;
44use std:: io;
@@ -55,7 +55,10 @@ crate struct Context<'tcx> {
5555 /// publicly reused items to redirect to the right location.
5656 pub ( super ) render_redirect_pages : bool ,
5757 /// The map used to ensure all generated 'id=' attributes are unique.
58- pub ( super ) id_map : RefCell < IdMap > ,
58+ ///
59+ /// INVARIANT: there is always at least one map in this list (because `mod_item_out` is never
60+ /// called without first calling `mod_item_in`).
61+ pub ( super ) id_maps : Vec < RefCell < IdMap > > ,
5962 /// Shared mutable state.
6063 ///
6164 /// Issue for improving the situation: [#82381][]
@@ -70,7 +73,7 @@ crate struct Context<'tcx> {
7073
7174// `Context` is cloned a lot, so we don't want the size to grow unexpectedly.
7275#[ cfg( target_arch = "x86_64" ) ]
73- rustc_data_structures:: static_assert_size!( Context <' _>, 104 ) ;
76+ rustc_data_structures:: static_assert_size!( Context <' _>, 88 ) ;
7477
7578/// Shared mutable state used in [`Context`] and elsewhere.
7679crate struct SharedContext < ' tcx > {
@@ -161,9 +164,12 @@ impl<'tcx> Context<'tcx> {
161164 & self . shared . tcx . sess
162165 }
163166
167+ pub ( super ) fn id_map ( & self ) -> RefMut < ' _ , IdMap > {
168+ self . id_maps . last ( ) . unwrap ( ) . borrow_mut ( )
169+ }
170+
164171 pub ( super ) fn derive_id ( & self , id : String ) -> String {
165- let mut map = self . id_map . borrow_mut ( ) ;
166- map. derive ( id)
172+ self . id_map ( ) . derive ( id)
167173 }
168174
169175 /// String representation of how to get back to the root path of the 'doc/'
@@ -502,7 +508,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
502508 current : Vec :: new ( ) ,
503509 dst,
504510 render_redirect_pages : false ,
505- id_map : RefCell :: new ( id_map) ,
511+ id_maps : vec ! [ RefCell :: new( id_map) ] ,
506512 shared : Rc :: new ( scx) ,
507513 include_sources,
508514 } ;
@@ -608,6 +614,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
608614 }
609615
610616 fn mod_item_in ( & mut self , item : & clean:: Item ) -> Result < ( ) , Error > {
617+ self . id_maps . push ( RefCell :: new ( IdMap :: new ( ) ) ) ;
611618 // Stripped modules survive the rustdoc passes (i.e., `strip-private`)
612619 // if they contain impls for public types. These modules can also
613620 // contain items such as publicly re-exported structures.
@@ -653,6 +660,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
653660 // Go back to where we were at
654661 self . dst . pop ( ) ;
655662 self . current . pop ( ) ;
663+ self . id_maps . pop ( ) ;
656664 Ok ( ( ) )
657665 }
658666
0 commit comments