2 use rustc_hir::def::Namespace::TypeNS;
3 use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
4 use rustc_interface::interface;
7 use std::cell::RefCell;
11 type Resolver = Rc<RefCell<interface::BoxedResolver>>;
12 // Letting the resolver escape at the end of the function leads to inconsistencies between the
13 // crates the TyCtxt sees and the resolver sees (because the resolver could load more crates
14 // after escaping). Hopefully `IntraLinkCrateLoader` gets all the crates we need ...
15 crate fn load_intra_link_crates(resolver: Resolver, krate: &ast::Crate) -> Resolver {
16 let mut loader = IntraLinkCrateLoader { current_mod: CRATE_DEF_ID, resolver };
17 // `walk_crate` doesn't visit the crate itself for some reason.
18 loader.load_links_in_attrs(&krate.attrs, krate.span);
19 ast::visit::walk_crate(&mut loader, krate);
23 struct IntraLinkCrateLoader {
24 current_mod: LocalDefId,
25 resolver: Rc<RefCell<interface::BoxedResolver>>,
28 impl IntraLinkCrateLoader {
29 fn load_links_in_attrs(&mut self, attrs: &[ast::Attribute], span: Span) {
30 use crate::html::markdown::markdown_links;
31 use crate::passes::collect_intra_doc_links::preprocess_link;
33 // FIXME: this probably needs to consider inlining
34 let attrs = crate::clean::Attributes::from_ast(attrs, None);
35 for (parent_module, doc) in attrs.collapsed_doc_value_by_module_level() {
37 for link in markdown_links(&doc.as_str()) {
39 let path_str = if let Some(Ok(x)) = preprocess_link(&link) {
44 self.resolver.borrow_mut().access(|resolver| {
45 let _ = resolver.resolve_str_path_error(
49 parent_module.unwrap_or(self.current_mod.to_def_id()),
57 impl ast::visit::Visitor<'_> for IntraLinkCrateLoader {
58 fn visit_item(&mut self, item: &ast::Item) {
59 use rustc_ast_lowering::ResolverAstLowering;
61 if let ast::ItemKind::Mod(..) = item.kind {
63 self.resolver.borrow_mut().access(|resolver| resolver.local_def_id(item.id));
64 let old_mod = mem::replace(&mut self.current_mod, new_mod);
66 self.load_links_in_attrs(&item.attrs, item.span);
67 ast::visit::walk_item(self, item);
69 self.current_mod = old_mod;
71 self.load_links_in_attrs(&item.attrs, item.span);
72 ast::visit::walk_item(self, item);