Skip to content

Commit 986aa36

Browse files
authored
Rollup merge of #60908 - GuillaumeGomez:errors, r=oli-obk
Fix lints handling in rustdoc Part of #60664: now lints are handled just like any other lints you would setup in rustc. Still remains to handle `missing code examples` and `missing_docs` as part of the same group. r? @oli-obk
2 parents 815d3ba + 6063777 commit 986aa36

File tree

9 files changed

+123
-25
lines changed

9 files changed

+123
-25
lines changed

src/bootstrap/test.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ impl Step for RustdocUi {
683683
target: self.target,
684684
mode: "ui",
685685
suite: "rustdoc-ui",
686-
path: None,
686+
path: Some("src/test/rustdoc-ui"),
687687
compare_mode: None,
688688
})
689689
}

src/librustc/lint/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,9 @@ fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum)
778778

779779
let push = builder.levels.push(&krate.attrs);
780780
builder.levels.register_id(hir::CRATE_HIR_ID);
781+
for macro_def in &krate.exported_macros {
782+
builder.levels.register_id(macro_def.hir_id);
783+
}
781784
intravisit::walk_crate(&mut builder, krate);
782785
builder.levels.pop(push);
783786

src/librustdoc/clean/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -3408,6 +3408,7 @@ pub struct Span {
34083408
pub locol: usize,
34093409
pub hiline: usize,
34103410
pub hicol: usize,
3411+
pub original: syntax_pos::Span,
34113412
}
34123413

34133414
impl Span {
@@ -3416,8 +3417,13 @@ impl Span {
34163417
filename: FileName::Anon(0),
34173418
loline: 0, locol: 0,
34183419
hiline: 0, hicol: 0,
3420+
original: syntax_pos::DUMMY_SP,
34193421
}
34203422
}
3423+
3424+
pub fn span(&self) -> syntax_pos::Span {
3425+
self.original
3426+
}
34213427
}
34223428

34233429
impl Clean<Span> for syntax_pos::Span {
@@ -3436,6 +3442,7 @@ impl Clean<Span> for syntax_pos::Span {
34363442
locol: lo.col.to_usize(),
34373443
hiline: hi.line,
34383444
hicol: hi.col.to_usize(),
3445+
original: *self,
34393446
}
34403447
}
34413448
}

src/librustdoc/passes/collect_intra_doc_links.rs

+25-9
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
321321
if let Ok(res) = self.resolve(path_str, ns, &current_item, parent_node) {
322322
res
323323
} else {
324-
resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
324+
resolution_failure(cx, &item, path_str, &dox, link_range);
325325
// This could just be a normal link or a broken link
326326
// we could potentially check if something is
327327
// "intra-doc-link-like" and warn in that case.
@@ -332,7 +332,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
332332
if let Ok(res) = self.resolve(path_str, ns, &current_item, parent_node) {
333333
res
334334
} else {
335-
resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
335+
resolution_failure(cx, &item, path_str, &dox, link_range);
336336
// This could just be a normal link.
337337
continue;
338338
}
@@ -357,7 +357,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
357357
};
358358

359359
if candidates.is_empty() {
360-
resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
360+
resolution_failure(cx, &item, path_str, &dox, link_range);
361361
// this could just be a normal link
362362
continue;
363363
}
@@ -368,7 +368,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
368368
} else {
369369
ambiguity_error(
370370
cx,
371-
&item.attrs,
371+
&item,
372372
path_str,
373373
&dox,
374374
link_range,
@@ -381,7 +381,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
381381
if let Some(res) = macro_resolve(cx, path_str) {
382382
(res, None)
383383
} else {
384-
resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
384+
resolution_failure(cx, &item, path_str, &dox, link_range);
385385
continue
386386
}
387387
}
@@ -452,16 +452,24 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option<Res> {
452452
/// line containing the failure as a note as well.
453453
fn resolution_failure(
454454
cx: &DocContext<'_>,
455-
attrs: &Attributes,
455+
item: &Item,
456456
path_str: &str,
457457
dox: &str,
458458
link_range: Option<Range<usize>>,
459459
) {
460+
let hir_id = match cx.as_local_hir_id(item.def_id) {
461+
Some(hir_id) => hir_id,
462+
None => {
463+
// If non-local, no need to check anything.
464+
return;
465+
}
466+
};
467+
let attrs = &item.attrs;
460468
let sp = span_of_attrs(attrs);
461469

462470
let mut diag = cx.tcx.struct_span_lint_hir(
463471
lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
464-
hir::CRATE_HIR_ID,
472+
hir_id,
465473
sp,
466474
&format!("`[{}]` cannot be resolved, ignoring it...", path_str),
467475
);
@@ -495,12 +503,20 @@ fn resolution_failure(
495503

496504
fn ambiguity_error(
497505
cx: &DocContext<'_>,
498-
attrs: &Attributes,
506+
item: &Item,
499507
path_str: &str,
500508
dox: &str,
501509
link_range: Option<Range<usize>>,
502510
candidates: PerNS<Option<Res>>,
503511
) {
512+
let hir_id = match cx.as_local_hir_id(item.def_id) {
513+
Some(hir_id) => hir_id,
514+
None => {
515+
// If non-local, no need to check anything.
516+
return;
517+
}
518+
};
519+
let attrs = &item.attrs;
504520
let sp = span_of_attrs(attrs);
505521

506522
let mut msg = format!("`{}` is ", path_str);
@@ -532,7 +548,7 @@ fn ambiguity_error(
532548

533549
let mut diag = cx.tcx.struct_span_lint_hir(
534550
lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
535-
hir::CRATE_HIR_ID,
551+
hir_id,
536552
sp,
537553
&msg,
538554
);

src/librustdoc/passes/mod.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Contains information about "passes", used to modify crate information during the documentation
22
//! process.
33
4-
use rustc::hir;
54
use rustc::hir::def_id::DefId;
65
use rustc::lint as lint;
76
use rustc::middle::privacy::AccessLevels;
@@ -314,10 +313,13 @@ pub fn look_for_tests<'tcx>(
314313
item: &Item,
315314
check_missing_code: bool,
316315
) {
317-
if cx.as_local_hir_id(item.def_id).is_none() {
318-
// If non-local, no need to check anything.
319-
return;
320-
}
316+
let hir_id = match cx.as_local_hir_id(item.def_id) {
317+
Some(hir_id) => hir_id,
318+
None => {
319+
// If non-local, no need to check anything.
320+
return;
321+
}
322+
};
321323

322324
struct Tests {
323325
found_tests: usize,
@@ -336,18 +338,19 @@ pub fn look_for_tests<'tcx>(
336338
find_testable_code(&dox, &mut tests, ErrorCodes::No);
337339

338340
if check_missing_code == true && tests.found_tests == 0 {
341+
let sp = span_of_attrs(&item.attrs).substitute_dummy(item.source.span());
339342
let mut diag = cx.tcx.struct_span_lint_hir(
340343
lint::builtin::MISSING_DOC_CODE_EXAMPLES,
341-
hir::CRATE_HIR_ID,
342-
span_of_attrs(&item.attrs),
344+
hir_id,
345+
sp,
343346
"Missing code example in this documentation");
344347
diag.emit();
345348
} else if check_missing_code == false &&
346349
tests.found_tests > 0 &&
347350
!cx.renderinfo.borrow().access_levels.is_doc_reachable(item.def_id) {
348351
let mut diag = cx.tcx.struct_span_lint_hir(
349352
lint::builtin::PRIVATE_DOC_TESTS,
350-
hir::CRATE_HIR_ID,
353+
hir_id,
351354
span_of_attrs(&item.attrs),
352355
"Documentation test in private item");
353356
diag.emit();

src/test/rustdoc-ui/doc-without-codeblock.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
//~ ERROR Missing code example in this documentation
2-
3-
#![deny(missing_doc_code_examples)]
1+
#![deny(missing_doc_code_examples)] //~ ERROR Missing code example in this documentation
42

53
/// Some docs.
64
//~^ ERROR Missing code example in this documentation

src/test/rustdoc-ui/doc-without-codeblock.stderr

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,35 @@
11
error: Missing code example in this documentation
2+
--> $DIR/doc-without-codeblock.rs:1:1
3+
|
4+
LL | / #![deny(missing_doc_code_examples)]
5+
LL | |
6+
LL | | /// Some docs.
7+
LL | |
8+
... |
9+
LL | | pub fn bar() {}
10+
LL | | }
11+
| |_^
212
|
313
note: lint level defined here
4-
--> $DIR/doc-without-codeblock.rs:3:9
14+
--> $DIR/doc-without-codeblock.rs:1:9
515
|
616
LL | #![deny(missing_doc_code_examples)]
717
| ^^^^^^^^^^^^^^^^^^^^^^^^^
818

919
error: Missing code example in this documentation
10-
--> $DIR/doc-without-codeblock.rs:5:1
20+
--> $DIR/doc-without-codeblock.rs:3:1
1121
|
1222
LL | /// Some docs.
1323
| ^^^^^^^^^^^^^^
1424

1525
error: Missing code example in this documentation
16-
--> $DIR/doc-without-codeblock.rs:9:1
26+
--> $DIR/doc-without-codeblock.rs:7:1
1727
|
1828
LL | /// And then, the princess died.
1929
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2030

2131
error: Missing code example in this documentation
22-
--> $DIR/doc-without-codeblock.rs:12:5
32+
--> $DIR/doc-without-codeblock.rs:10:5
2333
|
2434
LL | /// Or maybe not because she saved herself!
2535
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#![deny(missing_docs)]
2+
#![deny(missing_doc_code_examples)]
3+
4+
//! crate level doc
5+
//! ```
6+
//! println!("hello"):
7+
//! ```
8+
9+
10+
/// doc
11+
///
12+
/// ```
13+
/// println!("hello");
14+
/// ```
15+
fn test() {
16+
}
17+
18+
#[allow(missing_docs)]
19+
mod module1 { //~ ERROR
20+
}
21+
22+
#[allow(missing_doc_code_examples)]
23+
/// doc
24+
mod module2 {
25+
26+
/// doc
27+
pub fn test() {}
28+
}
29+
30+
/// doc
31+
///
32+
/// ```
33+
/// println!("hello");
34+
/// ```
35+
pub mod module3 {
36+
37+
/// doc
38+
//~^ ERROR
39+
pub fn test() {}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error: Missing code example in this documentation
2+
--> $DIR/lint-missing-doc-code-example.rs:19:1
3+
|
4+
LL | / mod module1 {
5+
LL | | }
6+
| |_^
7+
|
8+
note: lint level defined here
9+
--> $DIR/lint-missing-doc-code-example.rs:2:9
10+
|
11+
LL | #![deny(missing_doc_code_examples)]
12+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
13+
14+
error: Missing code example in this documentation
15+
--> $DIR/lint-missing-doc-code-example.rs:37:3
16+
|
17+
LL | /// doc
18+
| ^^^^^^^
19+
20+
error: aborting due to 2 previous errors
21+

0 commit comments

Comments
 (0)