Skip to content

Commit 2a90d31

Browse files
Rollup merge of #77249 - jyn514:private-links, r=Manishearth
Separate `private_intra_doc_links` and `broken_intra_doc_links` into separate lints This is not ideal because it means `deny(broken_intra_doc_links)` will no longer `deny(private_intra_doc_links)`. However, it can't be fixed with a new lint group, because `broken` is already in the `rustdoc` lint group; there would need to be a way to nest groups somehow. This also removes the early `return` so that the link will be generated even though it gives a warning. r? @Manishearth cc @ecstatic-morse (#77242 (comment))
2 parents 9f086fc + 80ffaed commit 2a90d31

File tree

9 files changed

+75
-12
lines changed

9 files changed

+75
-12
lines changed

compiler/rustc_lint/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
305305
add_lint_group!(
306306
"rustdoc",
307307
BROKEN_INTRA_DOC_LINKS,
308+
PRIVATE_INTRA_DOC_LINKS,
308309
INVALID_CODEBLOCK_ATTRIBUTES,
309310
MISSING_DOC_CODE_EXAMPLES,
310311
PRIVATE_DOC_TESTS

compiler/rustc_session/src/lint/builtin.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1826,6 +1826,17 @@ declare_lint! {
18261826
"failures in resolving intra-doc link targets"
18271827
}
18281828

1829+
declare_lint! {
1830+
/// This is a subset of `broken_intra_doc_links` that warns when linking from
1831+
/// a public item to a private one. This is a `rustdoc` only lint, see the
1832+
/// documentation in the [rustdoc book].
1833+
///
1834+
/// [rustdoc book]: ../../../rustdoc/lints.html#private_intra_doc_links
1835+
pub PRIVATE_INTRA_DOC_LINKS,
1836+
Warn,
1837+
"linking from a public item to a private one"
1838+
}
1839+
18291840
declare_lint! {
18301841
/// The `invalid_codeblock_attributes` lint detects code block attributes
18311842
/// in documentation examples that have potentially mis-typed values. This

src/doc/rustdoc/src/lints.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,46 @@ help: to link to the function, add parentheses
6262
6363
```
6464

65+
## private_intra_doc_links
66+
67+
This lint **warns by default**. This lint detects when [intra-doc links] from public to private items.
68+
For example:
69+
70+
```rust
71+
/// [private]
72+
pub fn public() {}
73+
fn private() {}
74+
```
75+
76+
This gives a warning that the link will be broken when it appears in your documentation:
77+
78+
```text
79+
warning: public documentation for `public` links to private item `private`
80+
--> priv.rs:1:6
81+
|
82+
1 | /// [private]
83+
| ^^^^^^^ this item is private
84+
|
85+
= note: `#[warn(private_intra_doc_links)]` on by default
86+
= note: this link will resolve properly if you pass `--document-private-items`
87+
```
88+
89+
Note that this has different behavior depending on whether you pass `--document-private-items` or not!
90+
If you document private items, then it will still generate a link, despite the warning:
91+
92+
```text
93+
warning: public documentation for `public` links to private item `private`
94+
--> priv.rs:1:6
95+
|
96+
1 | /// [private]
97+
| ^^^^^^^ this item is private
98+
|
99+
= note: `#[warn(private_intra_doc_links)]` on by default
100+
= note: this link resolves only because you passed `--document-private-items`, but will break without
101+
```
102+
103+
[intra-doc links]: linking-to-items-by-name.html
104+
65105
## missing_docs
66106

67107
This lint is **allowed by default**. It detects items missing documentation.

src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ use rustc_hir::def::{
1111
use rustc_hir::def_id::DefId;
1212
use rustc_middle::ty;
1313
use rustc_resolve::ParentScope;
14-
use rustc_session::lint;
14+
use rustc_session::lint::{
15+
builtin::{BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS},
16+
Lint,
17+
};
1518
use rustc_span::hygiene::MacroKind;
1619
use rustc_span::symbol::Ident;
1720
use rustc_span::symbol::Symbol;
@@ -988,7 +991,7 @@ impl LinkCollector<'_, '_> {
988991
let report_mismatch = |specified: Disambiguator, resolved: Disambiguator| {
989992
// The resolved item did not match the disambiguator; give a better error than 'not found'
990993
let msg = format!("incompatible link kind for `{}`", path_str);
991-
report_diagnostic(cx, &msg, &item, dox, &link_range, |diag, sp| {
994+
let callback = |diag: &mut DiagnosticBuilder<'_>, sp| {
992995
let note = format!(
993996
"this link resolved to {} {}, which is not {} {}",
994997
resolved.article(),
@@ -998,7 +1001,8 @@ impl LinkCollector<'_, '_> {
9981001
);
9991002
diag.note(&note);
10001003
suggest_disambiguator(resolved, diag, path_str, dox, sp, &link_range);
1001-
});
1004+
};
1005+
report_diagnostic(cx, BROKEN_INTRA_DOC_LINKS, &msg, &item, dox, &link_range, callback);
10021006
};
10031007
if let Res::PrimTy(..) = res {
10041008
match disambiguator {
@@ -1055,7 +1059,6 @@ impl LinkCollector<'_, '_> {
10551059
&& !self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_dst)
10561060
{
10571061
privacy_error(cx, &item, &path_str, dox, link_range);
1058-
return;
10591062
}
10601063
}
10611064
let id = register_res(cx, res);
@@ -1417,6 +1420,7 @@ impl Suggestion {
14171420
/// to it.
14181421
fn report_diagnostic(
14191422
cx: &DocContext<'_>,
1423+
lint: &'static Lint,
14201424
msg: &str,
14211425
item: &Item,
14221426
dox: &str,
@@ -1435,7 +1439,7 @@ fn report_diagnostic(
14351439
let attrs = &item.attrs;
14361440
let sp = span_of_attrs(attrs).unwrap_or(item.source.span());
14371441

1438-
cx.tcx.struct_span_lint_hir(lint::builtin::BROKEN_INTRA_DOC_LINKS, hir_id, sp, |lint| {
1442+
cx.tcx.struct_span_lint_hir(lint, hir_id, sp, |lint| {
14391443
let mut diag = lint.build(msg);
14401444

14411445
let span = link_range
@@ -1482,6 +1486,7 @@ fn resolution_failure(
14821486
) {
14831487
report_diagnostic(
14841488
collector.cx,
1489+
BROKEN_INTRA_DOC_LINKS,
14851490
&format!("unresolved link to `{}`", path_str),
14861491
item,
14871492
dox,
@@ -1695,7 +1700,7 @@ fn anchor_failure(
16951700
),
16961701
};
16971702

1698-
report_diagnostic(cx, &msg, item, dox, &link_range, |diag, sp| {
1703+
report_diagnostic(cx, BROKEN_INTRA_DOC_LINKS, &msg, item, dox, &link_range, |diag, sp| {
16991704
if let Some(sp) = sp {
17001705
diag.span_label(sp, "contains invalid anchor");
17011706
}
@@ -1734,7 +1739,7 @@ fn ambiguity_error(
17341739
}
17351740
}
17361741

1737-
report_diagnostic(cx, &msg, item, dox, &link_range, |diag, sp| {
1742+
report_diagnostic(cx, BROKEN_INTRA_DOC_LINKS, &msg, item, dox, &link_range, |diag, sp| {
17381743
if let Some(sp) = sp {
17391744
diag.span_label(sp, "ambiguous link");
17401745
} else {
@@ -1784,7 +1789,7 @@ fn privacy_error(
17841789
let msg =
17851790
format!("public documentation for `{}` links to private item `{}`", item_name, path_str);
17861791

1787-
report_diagnostic(cx, &msg, item, dox, &link_range, |diag, sp| {
1792+
report_diagnostic(cx, PRIVATE_INTRA_DOC_LINKS, &msg, item, dox, &link_range, |diag, sp| {
17881793
if let Some(sp) = sp {
17891794
diag.span_label(sp, "this item is private");
17901795
}

src/test/rustdoc-ui/intra-links-private.private.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ warning: public documentation for `DocMe` links to private item `DontDocMe`
44
LL | /// docs [DontDocMe]
55
| ^^^^^^^^^ this item is private
66
|
7-
= note: `#[warn(broken_intra_doc_links)]` on by default
7+
= note: `#[warn(private_intra_doc_links)]` on by default
88
= note: this link resolves only because you passed `--document-private-items`, but will break without
99

1010
warning: 1 warning emitted

src/test/rustdoc-ui/intra-links-private.public.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ warning: public documentation for `DocMe` links to private item `DontDocMe`
44
LL | /// docs [DontDocMe]
55
| ^^^^^^^^^ this item is private
66
|
7-
= note: `#[warn(broken_intra_doc_links)]` on by default
7+
= note: `#[warn(private_intra_doc_links)]` on by default
88
= note: this link will resolve properly if you pass `--document-private-items`
99

1010
warning: 1 warning emitted

src/test/rustdoc-ui/issue-74134.private.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ warning: public documentation for `public_item` links to private item `PrivateTy
44
LL | /// [`PrivateType`]
55
| ^^^^^^^^^^^^^ this item is private
66
|
7-
= note: `#[warn(broken_intra_doc_links)]` on by default
7+
= note: `#[warn(private_intra_doc_links)]` on by default
88
= note: this link resolves only because you passed `--document-private-items`, but will break without
99

1010
warning: 1 warning emitted

src/test/rustdoc-ui/issue-74134.public.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ warning: public documentation for `public_item` links to private item `PrivateTy
44
LL | /// [`PrivateType`]
55
| ^^^^^^^^^^^^^ this item is private
66
|
7-
= note: `#[warn(broken_intra_doc_links)]` on by default
7+
= note: `#[warn(private_intra_doc_links)]` on by default
88
= note: this link will resolve properly if you pass `--document-private-items`
99

1010
warning: 1 warning emitted
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#![crate_name = "private"]
2+
// compile-flags: --document-private-items
3+
/// docs [DontDocMe]
4+
// @has private/struct.DocMe.html '//*a[@href="../private/struct.DontDocMe.html"]' 'DontDocMe'
5+
pub struct DocMe;
6+
struct DontDocMe;

0 commit comments

Comments
 (0)