Skip to content

Commit b92a297

Browse files
committed
Move crate loader to collect_intra_doc_links::early
This groups the similar code together, and also allows making most of collect_intra_doc_links private again
1 parent 47d1ed9 commit b92a297

File tree

3 files changed

+80
-61
lines changed

3 files changed

+80
-61
lines changed

src/librustdoc/core.rs

+3-50
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use rustc_driver::abort_on_err;
55
use rustc_errors::emitter::{Emitter, EmitterWriter};
66
use rustc_errors::json::JsonEmitter;
77
use rustc_feature::UnstableFeatures;
8-
use rustc_hir::def::{Namespace::TypeNS, Res};
9-
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
8+
use rustc_hir::def::Res;
9+
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE};
1010
use rustc_hir::HirId;
1111
use rustc_hir::{
1212
intravisit::{self, NestedVisitorMap, Visitor},
@@ -356,54 +356,7 @@ crate fn create_resolver<'a>(
356356
let (krate, resolver, _) = &*parts;
357357
let resolver = resolver.borrow().clone();
358358

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;
369-
use crate::passes::collect_intra_doc_links::preprocess_link;
370-
371-
if let Some(doc) = attr.doc_str() {
372-
for link in markdown_links(&doc.as_str()) {
373-
let path_str = if let Some(Ok(x)) = preprocess_link(&link) {
374-
x.path_str
375-
} else {
376-
continue;
377-
};
378-
self.resolver.borrow_mut().access(|resolver| {
379-
let _ = resolver.resolve_str_path_error(
380-
attr.span,
381-
&path_str,
382-
TypeNS,
383-
self.current_mod,
384-
);
385-
});
386-
}
387-
}
388-
ast::visit::walk_attribute(self, attr);
389-
}
390-
391-
fn visit_item(&mut self, item: &ast::Item) {
392-
use rustc_ast_lowering::ResolverAstLowering;
393-
394-
if let ast::ItemKind::Mod(..) = item.kind {
395-
let new_mod =
396-
self.resolver.borrow_mut().access(|resolver| resolver.local_def_id(item.id));
397-
let old_mod = mem::replace(&mut self.current_mod, new_mod.to_def_id());
398-
ast::visit::walk_item(self, item);
399-
self.current_mod = old_mod;
400-
} else {
401-
ast::visit::walk_item(self, item);
402-
}
403-
}
404-
}
405-
let crate_id = LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id();
406-
let mut loader = IntraLinkCrateLoader { current_mod: crate_id, resolver };
359+
let mut loader = crate::passes::collect_intra_doc_links::IntraLinkCrateLoader::new(resolver);
407360
ast::visit::walk_crate(&mut loader, krate);
408361

409362
loader.resolver

src/librustdoc/passes/collect_intra_doc_links.rs

+14-11
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,16 @@ use crate::passes::Pass;
3939

4040
use super::span_of_attrs;
4141

42+
mod early;
43+
crate use early::IntraLinkCrateLoader;
44+
4245
crate const COLLECT_INTRA_DOC_LINKS: Pass = Pass {
4346
name: "collect-intra-doc-links",
4447
run: collect_intra_doc_links,
4548
description: "resolves intra-doc links",
4649
};
4750

48-
crate fn collect_intra_doc_links(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
51+
fn collect_intra_doc_links(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
4952
LinkCollector {
5053
cx,
5154
mod_ids: Vec::new(),
@@ -68,7 +71,7 @@ impl<'a> From<ResolutionFailure<'a>> for ErrorKind<'a> {
6871
}
6972

7073
#[derive(Copy, Clone, Debug, Hash)]
71-
crate enum Res {
74+
enum Res {
7275
Def(DefKind, DefId),
7376
Primitive(PrimitiveType),
7477
}
@@ -134,7 +137,7 @@ impl TryFrom<ResolveRes> for Res {
134137

135138
/// A link failed to resolve.
136139
#[derive(Debug)]
137-
crate enum ResolutionFailure<'a> {
140+
enum ResolutionFailure<'a> {
138141
/// This resolved, but with the wrong namespace.
139142
WrongNamespace {
140143
/// What the link resolved to.
@@ -172,7 +175,7 @@ crate enum ResolutionFailure<'a> {
172175
}
173176

174177
#[derive(Debug)]
175-
crate enum MalformedGenerics {
178+
enum MalformedGenerics {
176179
/// This link has unbalanced angle brackets.
177180
///
178181
/// For example, `Vec<T` should trigger this, as should `Vec<T>>`.
@@ -224,7 +227,7 @@ impl ResolutionFailure<'a> {
224227
}
225228
}
226229

227-
crate enum AnchorFailure {
230+
enum AnchorFailure {
228231
/// User error: `[std#x#y]` is not valid
229232
MultipleAnchors,
230233
/// The anchor provided by the user conflicts with Rustdoc's generated anchor.
@@ -892,7 +895,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
892895
}
893896
}
894897

895-
crate enum PreprocessingError<'a> {
898+
enum PreprocessingError<'a> {
896899
Anchor(AnchorFailure),
897900
Disambiguator(Range<usize>, String),
898901
Resolution(ResolutionFailure<'a>, String, Option<Disambiguator>),
@@ -904,8 +907,8 @@ impl From<AnchorFailure> for PreprocessingError<'_> {
904907
}
905908
}
906909

907-
crate struct PreprocessingInfo {
908-
crate path_str: String,
910+
struct PreprocessingInfo {
911+
path_str: String,
909912
disambiguator: Option<Disambiguator>,
910913
extra_fragment: Option<String>,
911914
link_text: String,
@@ -917,7 +920,7 @@ crate struct PreprocessingInfo {
917920
/// - `Some(Ok)` if the link is valid
918921
///
919922
/// `link_buffer` is needed for lifetime reasons; it will always be overwritten and the contents ignored.
920-
crate fn preprocess_link<'a>(
923+
fn preprocess_link<'a>(
921924
ori_link: &'a MarkdownLink,
922925
) -> Option<Result<PreprocessingInfo, PreprocessingError<'a>>> {
923926
// [] is mostly likely not supposed to be a link
@@ -1494,7 +1497,7 @@ fn should_ignore_link(path_str: &str) -> bool {
14941497

14951498
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
14961499
/// Disambiguators for a link.
1497-
crate enum Disambiguator {
1500+
enum Disambiguator {
14981501
/// `prim@`
14991502
///
15001503
/// This is buggy, see <https://github.com/rust-lang/rust/pull/77875#discussion_r503583103>
@@ -1523,7 +1526,7 @@ impl Disambiguator {
15231526
/// This returns `Ok(Some(...))` if a disambiguator was found,
15241527
/// `Ok(None)` if no disambiguator was found, or `Err(...)`
15251528
/// if there was a problem with the disambiguator.
1526-
crate fn from_str(link: &str) -> Result<Option<(Self, &str)>, (String, Range<usize>)> {
1529+
fn from_str(link: &str) -> Result<Option<(Self, &str)>, (String, Range<usize>)> {
15271530
use Disambiguator::{Kind, Namespace as NS, Primitive};
15281531

15291532
if let Some(idx) = link.find('@') {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use rustc_ast as ast;
2+
use rustc_hir::def::Namespace::TypeNS;
3+
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX};
4+
use rustc_interface::interface;
5+
6+
use std::cell::RefCell;
7+
use std::mem;
8+
use std::rc::Rc;
9+
10+
// Letting the resolver escape at the end of the function leads to inconsistencies between the
11+
// crates the TyCtxt sees and the resolver sees (because the resolver could load more crates
12+
// after escaping). Hopefully `IntraLinkCrateLoader` gets all the crates we need ...
13+
crate struct IntraLinkCrateLoader {
14+
current_mod: DefId,
15+
crate resolver: Rc<RefCell<interface::BoxedResolver>>,
16+
}
17+
18+
impl IntraLinkCrateLoader {
19+
crate fn new(resolver: Rc<RefCell<interface::BoxedResolver>>) -> Self {
20+
let crate_id = LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id();
21+
Self { current_mod: crate_id, resolver }
22+
}
23+
}
24+
25+
impl ast::visit::Visitor<'_> for IntraLinkCrateLoader {
26+
fn visit_attribute(&mut self, attr: &ast::Attribute) {
27+
use crate::html::markdown::markdown_links;
28+
use crate::passes::collect_intra_doc_links::preprocess_link;
29+
30+
if let Some(doc) = attr.doc_str() {
31+
for link in markdown_links(&doc.as_str()) {
32+
let path_str = if let Some(Ok(x)) = preprocess_link(&link) {
33+
x.path_str
34+
} else {
35+
continue;
36+
};
37+
self.resolver.borrow_mut().access(|resolver| {
38+
let _ = resolver.resolve_str_path_error(
39+
attr.span,
40+
&path_str,
41+
TypeNS,
42+
self.current_mod,
43+
);
44+
});
45+
}
46+
}
47+
ast::visit::walk_attribute(self, attr);
48+
}
49+
50+
fn visit_item(&mut self, item: &ast::Item) {
51+
use rustc_ast_lowering::ResolverAstLowering;
52+
53+
if let ast::ItemKind::Mod(..) = item.kind {
54+
let new_mod =
55+
self.resolver.borrow_mut().access(|resolver| resolver.local_def_id(item.id));
56+
let old_mod = mem::replace(&mut self.current_mod, new_mod.to_def_id());
57+
ast::visit::walk_item(self, item);
58+
self.current_mod = old_mod;
59+
} else {
60+
ast::visit::walk_item(self, item);
61+
}
62+
}
63+
}

0 commit comments

Comments
 (0)