Skip to content

Commit 8be3c2b

Browse files
committed
Auto merge of #107932 - petrochenkov:onlyexport, r=jyn514
rustdoc: Skip doc link resolution for non-exported items
2 parents 80a9330 + bec4eab commit 8be3c2b

File tree

5 files changed

+45
-11
lines changed

5 files changed

+45
-11
lines changed

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -4236,7 +4236,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
42364236
{
42374237
return;
42384238
}
4239-
ResolveDocLinks::Exported if !maybe_exported.eval(self.r) => {
4239+
ResolveDocLinks::Exported
4240+
if !maybe_exported.eval(self.r)
4241+
&& !rustdoc::has_primitive_or_keyword_docs(attrs) =>
4242+
{
42404243
return;
42414244
}
42424245
ResolveDocLinks::ExportedMetadata

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

+15-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc_ast as ast;
33
use rustc_ast::util::comments::beautify_doc_string;
44
use rustc_data_structures::fx::FxHashMap;
55
use rustc_span::def_id::DefId;
6-
use rustc_span::symbol::{kw, Symbol};
6+
use rustc_span::symbol::{kw, sym, Symbol};
77
use rustc_span::Span;
88
use std::{cmp, mem};
99

@@ -339,6 +339,20 @@ pub fn inner_docs(attrs: &[ast::Attribute]) -> bool {
339339
attrs.iter().find(|a| a.doc_str().is_some()).map_or(true, |a| a.style == ast::AttrStyle::Inner)
340340
}
341341

342+
/// Has `#[doc(primitive)]` or `#[doc(keyword)]`.
343+
pub fn has_primitive_or_keyword_docs(attrs: &[ast::Attribute]) -> bool {
344+
for attr in attrs {
345+
if attr.has_name(sym::doc) && let Some(items) = attr.meta_item_list() {
346+
for item in items {
347+
if item.has_name(sym::primitive) || item.has_name(sym::keyword) {
348+
return true;
349+
}
350+
}
351+
}
352+
}
353+
false
354+
}
355+
342356
/// Simplified version of the corresponding function in rustdoc.
343357
/// If the rustdoc version returns a successful result, this function must return the same result.
344358
/// Otherwise this function may return anything.

Diff for: src/librustdoc/core.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -217,13 +217,8 @@ pub(crate) fn create_config(
217217

218218
let crate_types =
219219
if proc_macro_crate { vec![CrateType::ProcMacro] } else { vec![CrateType::Rlib] };
220-
let resolve_doc_links = if *document_private {
221-
ResolveDocLinks::All
222-
} else {
223-
// Should be `ResolveDocLinks::Exported` in theory, but for some reason rustdoc
224-
// still tries to request resolutions for links on private items.
225-
ResolveDocLinks::All
226-
};
220+
let resolve_doc_links =
221+
if *document_private { ResolveDocLinks::All } else { ResolveDocLinks::Exported };
227222
let test = scrape_examples_options.map(|opts| opts.scrape_tests).unwrap_or(false);
228223
// plays with error output here!
229224
let sessopts = config::Options {

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

+11-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
1515
use rustc_hir::Mutability;
1616
use rustc_middle::ty::{fast_reject::TreatProjections, Ty, TyCtxt};
1717
use rustc_middle::{bug, ty};
18-
use rustc_resolve::rustdoc::MalformedGenerics;
19-
use rustc_resolve::rustdoc::{prepare_to_doc_link_resolution, strip_generics_from_path};
18+
use rustc_resolve::rustdoc::{has_primitive_or_keyword_docs, prepare_to_doc_link_resolution};
19+
use rustc_resolve::rustdoc::{strip_generics_from_path, MalformedGenerics};
2020
use rustc_session::lint::Lint;
2121
use rustc_span::hygiene::MacroKind;
2222
use rustc_span::symbol::{sym, Ident, Symbol};
@@ -899,6 +899,15 @@ fn preprocessed_markdown_links(s: &str) -> Vec<PreprocessedMarkdownLink> {
899899

900900
impl LinkCollector<'_, '_> {
901901
fn resolve_links(&mut self, item: &Item) {
902+
if !self.cx.render_options.document_private
903+
&& let Some(def_id) = item.item_id.as_def_id()
904+
&& let Some(def_id) = def_id.as_local()
905+
&& !self.cx.tcx.effective_visibilities(()).is_exported(def_id)
906+
&& !has_primitive_or_keyword_docs(&item.attrs.other_attrs) {
907+
// Skip link resolution for non-exported items.
908+
return;
909+
}
910+
902911
// We want to resolve in the lexical scope of the documentation.
903912
// In the presence of re-exports, this is not the same as the module of the item.
904913
// Rather than merging all documentation into one, resolve it one attribute at a time

Diff for: tests/rustdoc-ui/intra-doc/reachable-non-exported.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// The structure is reachable, but not exported, so rustdoc
2+
// doesn't attempt to request doc link resolutions on it.
3+
4+
// check-pass
5+
6+
mod private {
7+
/// [core::str::FromStr]
8+
pub struct ReachableButNotExported;
9+
}
10+
11+
pub fn foo() -> private::ReachableButNotExported {
12+
private::ReachableButNotExported
13+
}

0 commit comments

Comments
 (0)