Skip to content

Commit b5d4bd2

Browse files
Fix lints handling in rustdoc
1 parent 548add7 commit b5d4bd2

File tree

6 files changed

+85
-17
lines changed

6 files changed

+85
-17
lines changed

src/librustc/lint/mod.rs

Lines changed: 3 additions & 0 deletions
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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3405,6 +3405,7 @@ pub struct Span {
34053405
pub locol: usize,
34063406
pub hiline: usize,
34073407
pub hicol: usize,
3408+
pub original: syntax_pos::Span,
34083409
}
34093410

34103411
impl Span {
@@ -3413,8 +3414,13 @@ impl Span {
34133414
filename: FileName::Anon(0),
34143415
loline: 0, locol: 0,
34153416
hiline: 0, hicol: 0,
3417+
original: syntax_pos::DUMMY_SP,
34163418
}
34173419
}
3420+
3421+
pub fn span(&self) -> syntax_pos::Span {
3422+
self.original
3423+
}
34183424
}
34193425

34203426
impl Clean<Span> for syntax_pos::Span {
@@ -3433,6 +3439,7 @@ impl Clean<Span> for syntax_pos::Span {
34333439
locol: lo.col.to_usize(),
34343440
hiline: hi.line,
34353441
hicol: hi.col.to_usize(),
3442+
original: *self,
34363443
}
34373444
}
34383445
}

src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 25 additions & 9 deletions
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

Lines changed: 11 additions & 8 deletions
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();
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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 {
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+
pub fn test() {}
39+
}

src/test/rustdoc-ui/lint-missing-doc-code-example.stderr

Whitespace-only changes.

0 commit comments

Comments
 (0)