1
+ use rustc_ast as ast;
1
2
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
2
3
use rustc_data_structures:: sync:: { self , Lrc } ;
3
4
use rustc_driver:: abort_on_err;
@@ -22,7 +23,7 @@ use rustc_session::DiagnosticOutput;
22
23
use rustc_session:: Session ;
23
24
use rustc_span:: source_map;
24
25
use rustc_span:: symbol:: sym;
25
- use rustc_span:: { Span , DUMMY_SP } ;
26
+ use rustc_span:: Span ;
26
27
27
28
use std:: cell:: RefCell ;
28
29
use std:: collections:: hash_map:: Entry ;
@@ -348,42 +349,65 @@ crate fn create_config(
348
349
}
349
350
350
351
crate fn create_resolver < ' a > (
351
- externs : config:: Externs ,
352
352
queries : & Queries < ' a > ,
353
353
sess : & Session ,
354
354
) -> Rc < RefCell < interface:: BoxedResolver > > {
355
- let extern_names: Vec < String > = externs
356
- . iter ( )
357
- . filter ( |( _, entry) | entry. add_prelude )
358
- . map ( |( name, _) | name)
359
- . cloned ( )
360
- . collect ( ) ;
361
-
362
355
let parts = abort_on_err ( queries. expansion ( ) , sess) . peek ( ) ;
363
- let resolver = parts. 1 . borrow ( ) ;
364
-
365
- // Before we actually clone it, let's force all the extern'd crates to
366
- // actually be loaded, just in case they're only referred to inside
367
- // intra-doc links
368
- resolver. borrow_mut ( ) . access ( |resolver| {
369
- sess. time ( "load_extern_crates" , || {
370
- for extern_name in & extern_names {
371
- debug ! ( "loading extern crate {}" , extern_name) ;
372
- if let Err ( ( ) ) = resolver
373
- . resolve_str_path_error (
374
- DUMMY_SP ,
375
- extern_name,
376
- TypeNS ,
377
- LocalDefId { local_def_index : CRATE_DEF_INDEX } . to_def_id ( ) ,
378
- ) {
379
- warn ! ( "unable to resolve external crate {} (do you have an unused `--extern` crate?)" , extern_name)
380
- }
356
+ let ( krate, resolver, _) = & * parts;
357
+ let resolver = resolver. borrow ( ) . clone ( ) ;
358
+
359
+ // Letting the resolver escape at the end of the function leads to inconsistencies between the
360
+ // crates the TyCtxt sees and the resolver sees (because the resolver could load more crates
361
+ // after escaping). Hopefully `IntraLinkCrateLoader` gets all the crates we need ...
362
+ struct IntraLinkCrateLoader {
363
+ current_mod : DefId ,
364
+ resolver : Rc < RefCell < interface:: BoxedResolver > > ,
365
+ }
366
+ impl ast:: visit:: Visitor < ' _ > for IntraLinkCrateLoader {
367
+ fn visit_attribute ( & mut self , attr : & ast:: Attribute ) {
368
+ use crate :: html:: markdown:: { markdown_links, MarkdownLink } ;
369
+ use crate :: passes:: collect_intra_doc_links:: Disambiguator ;
370
+
371
+ if let Some ( doc) = attr. doc_str ( ) {
372
+ for MarkdownLink { link, .. } in markdown_links ( & doc. as_str ( ) ) {
373
+ // FIXME: this misses a *lot* of the preprocessing done in collect_intra_doc_links
374
+ // I think most of it shouldn't be necessary since we only need the crate prefix?
375
+ let path_str = match Disambiguator :: from_str ( & link) {
376
+ Ok ( x) => x. map_or ( link. as_str ( ) , |( _, p) | p) ,
377
+ Err ( _) => continue ,
378
+ } ;
379
+ self . resolver . borrow_mut ( ) . access ( |resolver| {
380
+ let _ = resolver. resolve_str_path_error (
381
+ attr. span ,
382
+ path_str,
383
+ TypeNS ,
384
+ self . current_mod ,
385
+ ) ;
386
+ } ) ;
387
+ }
381
388
}
382
- } ) ;
383
- } ) ;
389
+ ast:: visit:: walk_attribute ( self , attr) ;
390
+ }
391
+
392
+ fn visit_item ( & mut self , item : & ast:: Item ) {
393
+ use rustc_ast_lowering:: ResolverAstLowering ;
394
+
395
+ if let ast:: ItemKind :: Mod ( ..) = item. kind {
396
+ let new_mod =
397
+ self . resolver . borrow_mut ( ) . access ( |resolver| resolver. local_def_id ( item. id ) ) ;
398
+ let old_mod = mem:: replace ( & mut self . current_mod , new_mod. to_def_id ( ) ) ;
399
+ ast:: visit:: walk_item ( self , item) ;
400
+ self . current_mod = old_mod;
401
+ } else {
402
+ ast:: visit:: walk_item ( self , item) ;
403
+ }
404
+ }
405
+ }
406
+ let crate_id = LocalDefId { local_def_index : CRATE_DEF_INDEX } . to_def_id ( ) ;
407
+ let mut loader = IntraLinkCrateLoader { current_mod : crate_id, resolver } ;
408
+ ast:: visit:: walk_crate ( & mut loader, krate) ;
384
409
385
- // Now we're good to clone the resolver because everything should be loaded
386
- resolver. clone ( )
410
+ loader. resolver
387
411
}
388
412
389
413
crate fn run_global_ctxt (
0 commit comments