Skip doc link resolution for some crate types and non-exported items
This commit is contained in:
parent
3b0866272a
commit
da4ce6b41e
5 changed files with 106 additions and 19 deletions
|
@ -24,13 +24,13 @@ use rustc_hir::{BindingAnnotation, PrimTy, TraitCandidate};
|
|||
use rustc_middle::middle::resolve_lifetime::Set1;
|
||||
use rustc_middle::ty::DefIdTree;
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::config::CrateType;
|
||||
use rustc_session::config::{CrateType, ResolveDocLinks};
|
||||
use rustc_session::lint;
|
||||
use rustc_span::source_map::{respan, Spanned};
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::{BytePos, Span, SyntaxContext};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
use rustc_span::source_map::{respan, Spanned};
|
||||
use std::assert_matches::debug_assert_matches;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::{hash_map::Entry, BTreeSet};
|
||||
|
@ -494,6 +494,30 @@ impl<'a> PathSource<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// At this point for most items we can answer whether that item is exported or not,
|
||||
/// but some items like impls require type information to determine exported-ness, so we make a
|
||||
/// conservative estimate for them (e.g. based on nominal visibility).
|
||||
#[derive(Clone, Copy)]
|
||||
enum MaybeExported<'a> {
|
||||
Ok(NodeId),
|
||||
Impl(Option<DefId>),
|
||||
ImplItem(Result<DefId, &'a Visibility>),
|
||||
}
|
||||
|
||||
impl MaybeExported<'_> {
|
||||
fn eval(self, r: &Resolver<'_>) -> bool {
|
||||
let def_id = match self {
|
||||
MaybeExported::Ok(node_id) => Some(r.local_def_id(node_id)),
|
||||
MaybeExported::Impl(Some(trait_def_id)) | MaybeExported::ImplItem(Ok(trait_def_id)) => {
|
||||
trait_def_id.as_local()
|
||||
}
|
||||
MaybeExported::Impl(None) => return true,
|
||||
MaybeExported::ImplItem(Err(vis)) => return vis.kind.is_pub(),
|
||||
};
|
||||
def_id.map_or(true, |def_id| r.effective_visibilities.is_exported(def_id))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct DiagnosticMetadata<'ast> {
|
||||
/// The current trait's associated items' ident, used for diagnostic suggestions.
|
||||
|
@ -774,7 +798,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||
);
|
||||
}
|
||||
fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {
|
||||
self.resolve_doc_links(&foreign_item.attrs);
|
||||
self.resolve_doc_links(&foreign_item.attrs, MaybeExported::Ok(foreign_item.id));
|
||||
match foreign_item.kind {
|
||||
ForeignItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
|
||||
self.with_generic_param_rib(
|
||||
|
@ -1165,12 +1189,12 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||
}
|
||||
|
||||
fn visit_variant(&mut self, v: &'ast Variant) {
|
||||
self.resolve_doc_links(&v.attrs);
|
||||
self.resolve_doc_links(&v.attrs, MaybeExported::Ok(v.id));
|
||||
visit::walk_variant(self, v)
|
||||
}
|
||||
|
||||
fn visit_field_def(&mut self, f: &'ast FieldDef) {
|
||||
self.resolve_doc_links(&f.attrs);
|
||||
self.resolve_doc_links(&f.attrs, MaybeExported::Ok(f.id));
|
||||
visit::walk_field_def(self, f)
|
||||
}
|
||||
}
|
||||
|
@ -2201,8 +2225,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
fn resolve_item(&mut self, item: &'ast Item) {
|
||||
let mod_inner_docs =
|
||||
matches!(item.kind, ItemKind::Mod(..)) && rustdoc::inner_docs(&item.attrs);
|
||||
if !mod_inner_docs {
|
||||
self.resolve_doc_links(&item.attrs);
|
||||
if !mod_inner_docs && !matches!(item.kind, ItemKind::Impl(..)) {
|
||||
self.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id));
|
||||
}
|
||||
|
||||
let name = item.ident.name;
|
||||
|
@ -2249,7 +2273,14 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
..
|
||||
}) => {
|
||||
self.diagnostic_metadata.current_impl_items = Some(impl_items);
|
||||
self.resolve_implementation(generics, of_trait, &self_ty, item.id, impl_items);
|
||||
self.resolve_implementation(
|
||||
&item.attrs,
|
||||
generics,
|
||||
of_trait,
|
||||
&self_ty,
|
||||
item.id,
|
||||
impl_items,
|
||||
);
|
||||
self.diagnostic_metadata.current_impl_items = None;
|
||||
}
|
||||
|
||||
|
@ -2297,7 +2328,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
ItemKind::Mod(..) => {
|
||||
self.with_scope(item.id, |this| {
|
||||
if mod_inner_docs {
|
||||
this.resolve_doc_links(&item.attrs);
|
||||
this.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id));
|
||||
}
|
||||
let old_macro_rules = this.parent_scope.macro_rules;
|
||||
visit::walk_item(this, item);
|
||||
|
@ -2583,7 +2614,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
};
|
||||
|
||||
for item in trait_items {
|
||||
self.resolve_doc_links(&item.attrs);
|
||||
self.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id));
|
||||
match &item.kind {
|
||||
AssocItemKind::Const(_, ty, default) => {
|
||||
self.visit_ty(ty);
|
||||
|
@ -2671,6 +2702,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
|
||||
fn resolve_implementation(
|
||||
&mut self,
|
||||
attrs: &[ast::Attribute],
|
||||
generics: &'ast Generics,
|
||||
opt_trait_reference: &'ast Option<TraitRef>,
|
||||
self_type: &'ast Ty,
|
||||
|
@ -2701,6 +2733,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
opt_trait_reference.as_ref(),
|
||||
self_type,
|
||||
|this, trait_id| {
|
||||
this.resolve_doc_links(attrs, MaybeExported::Impl(trait_id));
|
||||
|
||||
let item_def_id = this.r.local_def_id(item_id);
|
||||
|
||||
// Register the trait definitions from here.
|
||||
|
@ -2734,7 +2768,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
debug!("resolve_implementation with_self_rib_ns(ValueNS, ...)");
|
||||
let mut seen_trait_items = Default::default();
|
||||
for item in impl_items {
|
||||
this.resolve_impl_item(&**item, &mut seen_trait_items);
|
||||
this.resolve_impl_item(&**item, &mut seen_trait_items, trait_id);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -2752,9 +2786,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
&mut self,
|
||||
item: &'ast AssocItem,
|
||||
seen_trait_items: &mut FxHashMap<DefId, Span>,
|
||||
trait_id: Option<DefId>,
|
||||
) {
|
||||
use crate::ResolutionError::*;
|
||||
self.resolve_doc_links(&item.attrs);
|
||||
self.resolve_doc_links(&item.attrs, MaybeExported::ImplItem(trait_id.ok_or(&item.vis)));
|
||||
match &item.kind {
|
||||
AssocItemKind::Const(_, ty, default) => {
|
||||
debug!("resolve_implementation AssocItemKind::Const");
|
||||
|
@ -4183,7 +4218,23 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
res
|
||||
}
|
||||
|
||||
fn resolve_doc_links(&mut self, attrs: &[Attribute]) {
|
||||
fn resolve_doc_links(&mut self, attrs: &[Attribute], maybe_exported: MaybeExported<'_>) {
|
||||
match self.r.session.opts.resolve_doc_links {
|
||||
ResolveDocLinks::None => return,
|
||||
ResolveDocLinks::ExportedMetadata
|
||||
if !self.r.session.crate_types().iter().copied().any(CrateType::has_metadata)
|
||||
|| !maybe_exported.eval(self.r) =>
|
||||
{
|
||||
return;
|
||||
}
|
||||
ResolveDocLinks::Exported if !maybe_exported.eval(self.r) => {
|
||||
return;
|
||||
}
|
||||
ResolveDocLinks::ExportedMetadata
|
||||
| ResolveDocLinks::Exported
|
||||
| ResolveDocLinks::All => {}
|
||||
}
|
||||
|
||||
if !attrs.iter().any(|attr| attr.may_have_doc_links()) {
|
||||
return;
|
||||
}
|
||||
|
@ -4283,7 +4334,7 @@ impl<'a> Resolver<'a> {
|
|||
pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) {
|
||||
visit::walk_crate(&mut LifetimeCountVisitor { r: self }, krate);
|
||||
let mut late_resolution_visitor = LateResolutionVisitor::new(self);
|
||||
late_resolution_visitor.resolve_doc_links(&krate.attrs);
|
||||
late_resolution_visitor.resolve_doc_links(&krate.attrs, MaybeExported::Ok(CRATE_NODE_ID));
|
||||
visit::walk_crate(&mut late_resolution_visitor, krate);
|
||||
for (id, span) in late_resolution_visitor.diagnostic_metadata.unused_labels.iter() {
|
||||
self.lint_buffer.buffer_lint(lint::builtin::UNUSED_LABELS, *id, *span, "unused label");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue