@@ -3,6 +3,7 @@ use std::mem;
33use  rustc_attr_data_structures:: StabilityLevel ; 
44use  rustc_data_structures:: fx:: { FxHashMap ,  FxHashSet ,  FxIndexMap ,  FxIndexSet } ; 
55use  rustc_hir:: def_id:: { CrateNum ,  DefId ,  DefIdMap ,  DefIdSet } ; 
6+ use  rustc_metadata:: creader:: CStore ; 
67use  rustc_middle:: ty:: { self ,  TyCtxt } ; 
78use  rustc_span:: Symbol ; 
89use  tracing:: debug; 
@@ -158,18 +159,33 @@ impl Cache {
158159        assert ! ( cx. external_traits. is_empty( ) ) ; 
159160        cx. cache . traits  = mem:: take ( & mut  krate. external_traits ) ; 
160161
162+         let  render_options = & cx. render_options ; 
163+         let  extern_url_takes_precedence = render_options. extern_html_root_takes_precedence ; 
164+         let  dst = & render_options. output ; 
165+ 
166+         // Make `--extern-html-root-url` support the same names as `--extern` whenever possible 
167+         let  cstore = CStore :: from_tcx ( tcx) ; 
168+         for  ( name,  extern_url)  in  & render_options. extern_html_root_urls  { 
169+             if  let  Some ( crate_num)  = cstore. resolved_extern_crate ( Symbol :: intern ( name) )  { 
170+                 let  e = ExternalCrate  {  crate_num } ; 
171+                 let  location = e. location ( Some ( extern_url) ,  extern_url_takes_precedence,  dst,  tcx) ; 
172+                 cx. cache . extern_locations . insert ( e. crate_num ,  location) ; 
173+             } 
174+         } 
175+ 
161176        // Cache where all our extern crates are located 
162-         // FIXME: this part  is specific to HTML so it'd be nice to remove it from  the common code  
177+         // This  is also used in  the JSON output.  
163178        for  & crate_num in  tcx. crates ( ( ) )  { 
164179            let  e = ExternalCrate  {  crate_num } ; 
165180
166181            let  name = e. name ( tcx) ; 
167-             let  render_options = & cx. render_options ; 
168-             let  extern_url = render_options. extern_html_root_urls . get ( name. as_str ( ) ) . map ( |u| & * * u) ; 
169-             let  extern_url_takes_precedence = render_options. extern_html_root_takes_precedence ; 
170-             let  dst = & render_options. output ; 
171-             let  location = e. location ( extern_url,  extern_url_takes_precedence,  dst,  tcx) ; 
172-             cx. cache . extern_locations . insert ( e. crate_num ,  location) ; 
182+             cx. cache . extern_locations . entry ( e. crate_num ) . or_insert_with ( || { 
183+                 // falls back to matching by crates' own names, because 
184+                 // transitive dependencies and injected crates may be loaded without `--extern` 
185+                 let  extern_url =
186+                     render_options. extern_html_root_urls . get ( name. as_str ( ) ) . map ( |u| & * * u) ; 
187+                 e. location ( extern_url,  extern_url_takes_precedence,  dst,  tcx) 
188+             } ) ; 
173189            cx. cache . external_paths . insert ( e. def_id ( ) ,  ( vec ! [ name] ,  ItemType :: Module ) ) ; 
174190        } 
175191
0 commit comments