Skip to content

Commit 69d6c3b

Browse files
committed
rustdoc: Early doc link resolution fixes and refactorings
1 parent c2afaba commit 69d6c3b

File tree

10 files changed

+180
-113
lines changed

10 files changed

+180
-113
lines changed

Diff for: compiler/rustc_metadata/src/rmeta/decoder.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -1169,14 +1169,18 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
11691169
}
11701170
}
11711171

1172-
fn get_associated_item_def_ids(self, tcx: TyCtxt<'tcx>, id: DefIndex) -> &'tcx [DefId] {
1173-
if let Some(children) = self.root.tables.children.get(self, id) {
1174-
tcx.arena.alloc_from_iter(
1175-
children.decode((self, tcx.sess)).map(|child_index| self.local_def_id(child_index)),
1176-
)
1177-
} else {
1178-
&[]
1179-
}
1172+
fn get_associated_item_def_ids(
1173+
self,
1174+
id: DefIndex,
1175+
sess: &'a Session,
1176+
) -> impl Iterator<Item = DefId> + 'a {
1177+
self.root
1178+
.tables
1179+
.children
1180+
.get(self, id)
1181+
.unwrap_or_else(Lazy::empty)
1182+
.decode((self, sess))
1183+
.map(move |child_index| self.local_def_id(child_index))
11801184
}
11811185

11821186
fn get_associated_item(self, id: DefIndex) -> ty::AssocItem {

Diff for: compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,9 @@ provide! { <'tcx> tcx, def_id, other, cdata,
160160
let _ = cdata;
161161
tcx.calculate_dtor(def_id, |_,_| Ok(()))
162162
}
163-
associated_item_def_ids => { cdata.get_associated_item_def_ids(tcx, def_id.index) }
163+
associated_item_def_ids => {
164+
tcx.arena.alloc_from_iter(cdata.get_associated_item_def_ids(def_id.index, tcx.sess))
165+
}
164166
associated_item => { cdata.get_associated_item(def_id.index) }
165167
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
166168
is_foreign_item => { cdata.is_foreign_item(def_id.index) }

Diff for: compiler/rustc_resolve/src/build_reduced_graph.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1248,7 +1248,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
12481248
};
12491249
let binding = (res, vis, span, expansion).to_name_binding(self.r.arenas);
12501250
self.r.set_binding_parent_module(binding, parent_scope.module);
1251-
self.r.all_macros.insert(ident.name, res);
1251+
self.r.all_macro_rules.insert(ident.name, res);
12521252
if is_macro_export {
12531253
let module = self.r.graph_root;
12541254
self.r.define(module, ident, MacroNS, (res, vis, span, expansion, IsMacroExport));

Diff for: compiler/rustc_resolve/src/lib.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1003,7 +1003,8 @@ pub struct Resolver<'a> {
10031003
registered_attrs: FxHashSet<Ident>,
10041004
registered_tools: RegisteredTools,
10051005
macro_use_prelude: FxHashMap<Symbol, &'a NameBinding<'a>>,
1006-
all_macros: FxHashMap<Symbol, Res>,
1006+
/// FIXME: The only user of this is a doc link resolution hack for rustdoc.
1007+
all_macro_rules: FxHashMap<Symbol, Res>,
10071008
macro_map: FxHashMap<DefId, Lrc<SyntaxExtension>>,
10081009
dummy_ext_bang: Lrc<SyntaxExtension>,
10091010
dummy_ext_derive: Lrc<SyntaxExtension>,
@@ -1385,7 +1386,7 @@ impl<'a> Resolver<'a> {
13851386
registered_attrs,
13861387
registered_tools,
13871388
macro_use_prelude: FxHashMap::default(),
1388-
all_macros: FxHashMap::default(),
1389+
all_macro_rules: Default::default(),
13891390
macro_map: FxHashMap::default(),
13901391
dummy_ext_bang: Lrc::new(SyntaxExtension::dummy_bang(session.edition())),
13911392
dummy_ext_derive: Lrc::new(SyntaxExtension::dummy_derive(session.edition())),
@@ -3311,8 +3312,8 @@ impl<'a> Resolver<'a> {
33113312
}
33123313

33133314
// For rustdoc.
3314-
pub fn all_macros(&self) -> &FxHashMap<Symbol, Res> {
3315-
&self.all_macros
3315+
pub fn take_all_macro_rules(&mut self) -> FxHashMap<Symbol, Res> {
3316+
mem::take(&mut self.all_macro_rules)
33163317
}
33173318

33183319
/// For rustdoc.

Diff for: src/librustdoc/core.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_ast::NodeId;
12
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
23
use rustc_data_structures::sync::{self, Lrc};
34
use rustc_errors::emitter::{Emitter, EmitterWriter};
@@ -17,7 +18,7 @@ use rustc_session::lint;
1718
use rustc_session::DiagnosticOutput;
1819
use rustc_session::Session;
1920
use rustc_span::symbol::sym;
20-
use rustc_span::{source_map, Span};
21+
use rustc_span::{source_map, Span, Symbol};
2122

2223
use std::cell::RefCell;
2324
use std::lazy::SyncLazy;
@@ -38,6 +39,7 @@ crate struct ResolverCaches {
3839
crate traits_in_scope: DefIdMap<Vec<TraitCandidate>>,
3940
crate all_traits: Option<Vec<DefId>>,
4041
crate all_trait_impls: Option<Vec<DefId>>,
42+
crate all_macro_rules: FxHashMap<Symbol, Res<NodeId>>,
4143
}
4244

4345
crate struct DocContext<'tcx> {

Diff for: src/librustdoc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#![feature(control_flow_enum)]
1111
#![feature(box_syntax)]
1212
#![feature(drain_filter)]
13+
#![feature(let_chains)]
1314
#![feature(let_else)]
1415
#![feature(nll)]
1516
#![feature(test)]

Diff for: src/librustdoc/passes/collect_intra_doc_links.rs

+23-24
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,11 @@
22
//!
33
//! [RFC 1946]: https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md
44
5+
use pulldown_cmark::LinkType;
56
use rustc_data_structures::{fx::FxHashMap, intern::Interned, stable_set::FxHashSet};
67
use rustc_errors::{Applicability, Diagnostic};
7-
use rustc_hir::def::{
8-
DefKind,
9-
Namespace::{self, *},
10-
PerNS,
11-
};
8+
use rustc_hir::def::Namespace::*;
9+
use rustc_hir::def::{DefKind, Namespace, PerNS};
1210
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
1311
use rustc_hir::Mutability;
1412
use rustc_middle::ty::{DefIdTree, Ty, TyCtxt};
@@ -19,10 +17,7 @@ use rustc_span::symbol::{sym, Ident, Symbol};
1917
use rustc_span::{BytePos, DUMMY_SP};
2018
use smallvec::{smallvec, SmallVec};
2119

22-
use pulldown_cmark::LinkType;
23-
2420
use std::borrow::Cow;
25-
use std::convert::{TryFrom, TryInto};
2621
use std::fmt::Write;
2722
use std::mem;
2823
use std::ops::Range;
@@ -487,25 +482,13 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
487482
item_id: ItemId,
488483
module_id: DefId,
489484
) -> Result<Res, ResolutionFailure<'a>> {
490-
self.cx.enter_resolver(|resolver| {
491-
// NOTE: this needs 2 separate lookups because `resolve_rustdoc_path` doesn't take
492-
// lexical scope into account (it ignores all macros not defined at the mod-level)
493-
debug!("resolving {} as a macro in the module {:?}", path_str, module_id);
494-
if let Some(res) = resolver.resolve_rustdoc_path(path_str, MacroNS, module_id) {
495-
// don't resolve builtins like `#[derive]`
496-
if let Ok(res) = res.try_into() {
497-
return Ok(res);
498-
}
499-
}
500-
if let Some(&res) = resolver.all_macros().get(&Symbol::intern(path_str)) {
501-
return Ok(res.try_into().unwrap());
502-
}
503-
Err(ResolutionFailure::NotResolved {
485+
self.resolve_path(path_str, MacroNS, item_id, module_id).ok_or_else(|| {
486+
ResolutionFailure::NotResolved {
504487
item_id,
505488
module_id,
506489
partial_res: None,
507490
unresolved: path_str.into(),
508-
})
491+
}
509492
})
510493
}
511494

@@ -539,6 +522,21 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
539522
})
540523
}
541524

525+
/// HACK: Try to search the macro name in the list of all `macro_rules` items in the crate.
526+
/// Used when nothing else works, may often give an incorrect result.
527+
fn resolve_macro_rules(&self, path_str: &str, ns: Namespace) -> Option<Res> {
528+
if ns != MacroNS {
529+
return None;
530+
}
531+
532+
self.cx
533+
.resolver_caches
534+
.all_macro_rules
535+
.get(&Symbol::intern(path_str))
536+
.copied()
537+
.and_then(|res| res.try_into().ok())
538+
}
539+
542540
/// Convenience wrapper around `resolve_rustdoc_path`.
543541
///
544542
/// This also handles resolving `true` and `false` as booleans.
@@ -560,7 +558,8 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
560558
.cx
561559
.enter_resolver(|resolver| resolver.resolve_rustdoc_path(path_str, ns, module_id))
562560
.and_then(|res| res.try_into().ok())
563-
.or_else(|| resolve_primitive(path_str, ns));
561+
.or_else(|| resolve_primitive(path_str, ns))
562+
.or_else(|| self.resolve_macro_rules(path_str, ns));
564563
debug!("{} resolved to {:?} in namespace {:?}", path_str, result, ns);
565564
result
566565
}

0 commit comments

Comments
 (0)