@@ -102,6 +102,63 @@ impl hash::Hash for RustdocExternMap {
102102 }
103103}
104104
105+ /// Recursively generate html root url for all units and their children.
106+ ///
107+ /// This is needed because in case there is a reexport of foreign reexport, you
108+ /// need to have information about grand-children deps level (deps of your deps).
109+ fn build_all_urls (
110+ build_runner : & BuildRunner < ' _ , ' _ > ,
111+ rustdoc : & mut ProcessBuilder ,
112+ unit : & Unit ,
113+ name2url : & HashMap < & String , Url > ,
114+ map : & RustdocExternMap ,
115+ unstable_opts : & mut bool ,
116+ ) {
117+ for dep in build_runner. unit_deps ( unit) {
118+ if !dep. unit . target . is_linkable ( ) || dep. unit . mode . is_doc ( ) {
119+ continue ;
120+ }
121+ for ( registry, location) in & map. registries {
122+ let sid = dep. unit . pkg . package_id ( ) . source_id ( ) ;
123+ let matches_registry = || -> bool {
124+ if !sid. is_registry ( ) {
125+ return false ;
126+ }
127+ if sid. is_crates_io ( ) {
128+ return registry == CRATES_IO_REGISTRY ;
129+ }
130+ if let Some ( index_url) = name2url. get ( registry) {
131+ return index_url == sid. url ( ) ;
132+ }
133+ false
134+ } ;
135+ if matches_registry ( ) {
136+ let mut url = location. clone ( ) ;
137+ if !url. contains ( "{pkg_name}" ) && !url. contains ( "{version}" ) {
138+ if !url. ends_with ( '/' ) {
139+ url. push ( '/' ) ;
140+ }
141+ url. push_str ( "{pkg_name}/{version}/" ) ;
142+ }
143+ let url = url
144+ . replace ( "{pkg_name}" , & dep. unit . pkg . name ( ) )
145+ . replace ( "{version}" , & dep. unit . pkg . version ( ) . to_string ( ) ) ;
146+ rustdoc. arg ( "--extern-html-root-url" ) ;
147+ rustdoc. arg ( format ! ( "{}={}" , dep. unit. target. crate_name( ) , url) ) ;
148+ * unstable_opts = true ;
149+ }
150+ }
151+ build_all_urls (
152+ build_runner,
153+ rustdoc,
154+ & dep. unit ,
155+ name2url,
156+ map,
157+ unstable_opts,
158+ ) ;
159+ }
160+ }
161+
105162/// Adds unstable flag [`--extern-html-root-url`][1] to the given `rustdoc`
106163/// invocation. This is for unstable feature [`-Zrustdoc-map`][2].
107164///
@@ -135,40 +192,14 @@ pub fn add_root_urls(
135192 }
136193 } )
137194 . collect ( ) ;
138- for dep in build_runner. unit_deps ( unit) {
139- if dep. unit . target . is_linkable ( ) && !dep. unit . mode . is_doc ( ) {
140- for ( registry, location) in & map. registries {
141- let sid = dep. unit . pkg . package_id ( ) . source_id ( ) ;
142- let matches_registry = || -> bool {
143- if !sid. is_registry ( ) {
144- return false ;
145- }
146- if sid. is_crates_io ( ) {
147- return registry == CRATES_IO_REGISTRY ;
148- }
149- if let Some ( index_url) = name2url. get ( registry) {
150- return index_url == sid. url ( ) ;
151- }
152- false
153- } ;
154- if matches_registry ( ) {
155- let mut url = location. clone ( ) ;
156- if !url. contains ( "{pkg_name}" ) && !url. contains ( "{version}" ) {
157- if !url. ends_with ( '/' ) {
158- url. push ( '/' ) ;
159- }
160- url. push_str ( "{pkg_name}/{version}/" ) ;
161- }
162- let url = url
163- . replace ( "{pkg_name}" , & dep. unit . pkg . name ( ) )
164- . replace ( "{version}" , & dep. unit . pkg . version ( ) . to_string ( ) ) ;
165- rustdoc. arg ( "--extern-html-root-url" ) ;
166- rustdoc. arg ( format ! ( "{}={}" , dep. unit. target. crate_name( ) , url) ) ;
167- unstable_opts = true ;
168- }
169- }
170- }
171- }
195+ build_all_urls (
196+ build_runner,
197+ rustdoc,
198+ unit,
199+ & name2url,
200+ map,
201+ & mut unstable_opts,
202+ ) ;
172203 let std_url = match & map. std {
173204 None | Some ( RustdocExternMode :: Remote ) => None ,
174205 Some ( RustdocExternMode :: Local ) => {
0 commit comments