Skip to content

Fix lints handling in rustdoc #60908

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/bootstrap/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ impl Step for RustdocUi {
target: self.target,
mode: "ui",
suite: "rustdoc-ui",
path: None,
path: Some("src/test/rustdoc-ui"),
compare_mode: None,
})
}
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/lint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,9 @@ fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum)

let push = builder.levels.push(&krate.attrs);
builder.levels.register_id(hir::CRATE_HIR_ID);
for macro_def in &krate.exported_macros {
builder.levels.register_id(macro_def.hir_id);
}
intravisit::walk_crate(&mut builder, krate);
builder.levels.pop(push);

Expand Down
7 changes: 7 additions & 0 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3405,6 +3405,7 @@ pub struct Span {
pub locol: usize,
pub hiline: usize,
pub hicol: usize,
pub original: syntax_pos::Span,
}

impl Span {
Expand All @@ -3413,8 +3414,13 @@ impl Span {
filename: FileName::Anon(0),
loline: 0, locol: 0,
hiline: 0, hicol: 0,
original: syntax_pos::DUMMY_SP,
}
}

pub fn span(&self) -> syntax_pos::Span {
self.original
}
}

impl Clean<Span> for syntax_pos::Span {
Expand All @@ -3433,6 +3439,7 @@ impl Clean<Span> for syntax_pos::Span {
locol: lo.col.to_usize(),
hiline: hi.line,
hicol: hi.col.to_usize(),
original: *self,
}
}
}
Expand Down
34 changes: 25 additions & 9 deletions src/librustdoc/passes/collect_intra_doc_links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
if let Ok(res) = self.resolve(path_str, ns, &current_item, parent_node) {
res
} else {
resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
resolution_failure(cx, &item, path_str, &dox, link_range);
// This could just be a normal link or a broken link
// we could potentially check if something is
// "intra-doc-link-like" and warn in that case.
Expand All @@ -332,7 +332,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
if let Ok(res) = self.resolve(path_str, ns, &current_item, parent_node) {
res
} else {
resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
resolution_failure(cx, &item, path_str, &dox, link_range);
// This could just be a normal link.
continue;
}
Expand All @@ -357,7 +357,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
};

if candidates.is_empty() {
resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
resolution_failure(cx, &item, path_str, &dox, link_range);
// this could just be a normal link
continue;
}
Expand All @@ -368,7 +368,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
} else {
ambiguity_error(
cx,
&item.attrs,
&item,
path_str,
&dox,
link_range,
Expand All @@ -381,7 +381,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
if let Some(res) = macro_resolve(cx, path_str) {
(res, None)
} else {
resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
resolution_failure(cx, &item, path_str, &dox, link_range);
continue
}
}
Expand Down Expand Up @@ -452,16 +452,24 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option<Res> {
/// line containing the failure as a note as well.
fn resolution_failure(
cx: &DocContext<'_>,
attrs: &Attributes,
item: &Item,
path_str: &str,
dox: &str,
link_range: Option<Range<usize>>,
) {
let hir_id = match cx.as_local_hir_id(item.def_id) {
Some(hir_id) => hir_id,
None => {
// If non-local, no need to check anything.
return;
}
};
let attrs = &item.attrs;
let sp = span_of_attrs(attrs);

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

fn ambiguity_error(
cx: &DocContext<'_>,
attrs: &Attributes,
item: &Item,
path_str: &str,
dox: &str,
link_range: Option<Range<usize>>,
candidates: PerNS<Option<Res>>,
) {
let hir_id = match cx.as_local_hir_id(item.def_id) {
Some(hir_id) => hir_id,
None => {
// If non-local, no need to check anything.
return;
}
};
let attrs = &item.attrs;
let sp = span_of_attrs(attrs);

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

let mut diag = cx.tcx.struct_span_lint_hir(
lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
hir::CRATE_HIR_ID,
hir_id,
sp,
&msg,
);
Expand Down
19 changes: 11 additions & 8 deletions src/librustdoc/passes/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Contains information about "passes", used to modify crate information during the documentation
//! process.

use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::lint as lint;
use rustc::middle::privacy::AccessLevels;
Expand Down Expand Up @@ -314,10 +313,13 @@ pub fn look_for_tests<'tcx>(
item: &Item,
check_missing_code: bool,
) {
if cx.as_local_hir_id(item.def_id).is_none() {
// If non-local, no need to check anything.
return;
}
let hir_id = match cx.as_local_hir_id(item.def_id) {
Some(hir_id) => hir_id,
None => {
// If non-local, no need to check anything.
return;
}
};

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

if check_missing_code == true && tests.found_tests == 0 {
let sp = span_of_attrs(&item.attrs).substitute_dummy(item.source.span());
let mut diag = cx.tcx.struct_span_lint_hir(
lint::builtin::MISSING_DOC_CODE_EXAMPLES,
hir::CRATE_HIR_ID,
span_of_attrs(&item.attrs),
hir_id,
sp,
"Missing code example in this documentation");
diag.emit();
} else if check_missing_code == false &&
tests.found_tests > 0 &&
!cx.renderinfo.borrow().access_levels.is_doc_reachable(item.def_id) {
let mut diag = cx.tcx.struct_span_lint_hir(
lint::builtin::PRIVATE_DOC_TESTS,
hir::CRATE_HIR_ID,
hir_id,
span_of_attrs(&item.attrs),
"Documentation test in private item");
diag.emit();
Expand Down
4 changes: 1 addition & 3 deletions src/test/rustdoc-ui/doc-without-codeblock.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
//~ ERROR Missing code example in this documentation

#![deny(missing_doc_code_examples)]
#![deny(missing_doc_code_examples)] //~ ERROR Missing code example in this documentation

/// Some docs.
//~^ ERROR Missing code example in this documentation
Expand Down
18 changes: 14 additions & 4 deletions src/test/rustdoc-ui/doc-without-codeblock.stderr
Original file line number Diff line number Diff line change
@@ -1,25 +1,35 @@
error: Missing code example in this documentation
--> $DIR/doc-without-codeblock.rs:1:1
|
LL | / #![deny(missing_doc_code_examples)]
LL | |
LL | | /// Some docs.
LL | |
... |
LL | | pub fn bar() {}
LL | | }
| |_^
|
note: lint level defined here
--> $DIR/doc-without-codeblock.rs:3:9
--> $DIR/doc-without-codeblock.rs:1:9
|
LL | #![deny(missing_doc_code_examples)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^

error: Missing code example in this documentation
--> $DIR/doc-without-codeblock.rs:5:1
--> $DIR/doc-without-codeblock.rs:3:1
|
LL | /// Some docs.
| ^^^^^^^^^^^^^^

error: Missing code example in this documentation
--> $DIR/doc-without-codeblock.rs:9:1
--> $DIR/doc-without-codeblock.rs:7:1
|
LL | /// And then, the princess died.
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: Missing code example in this documentation
--> $DIR/doc-without-codeblock.rs:12:5
--> $DIR/doc-without-codeblock.rs:10:5
|
LL | /// Or maybe not because she saved herself!
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
40 changes: 40 additions & 0 deletions src/test/rustdoc-ui/lint-missing-doc-code-example.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#![deny(missing_docs)]
#![deny(missing_doc_code_examples)]

//! crate level doc
//! ```
//! println!("hello"):
//! ```


/// doc
///
/// ```
/// println!("hello");
/// ```
fn test() {
}

#[allow(missing_docs)]
mod module1 { //~ ERROR
}

#[allow(missing_doc_code_examples)]
/// doc
mod module2 {

/// doc
pub fn test() {}
}

/// doc
///
/// ```
/// println!("hello");
/// ```
pub mod module3 {

/// doc
//~^ ERROR
pub fn test() {}
}
21 changes: 21 additions & 0 deletions src/test/rustdoc-ui/lint-missing-doc-code-example.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error: Missing code example in this documentation
--> $DIR/lint-missing-doc-code-example.rs:19:1
|
LL | / mod module1 {
LL | | }
| |_^
|
note: lint level defined here
--> $DIR/lint-missing-doc-code-example.rs:2:9
|
LL | #![deny(missing_doc_code_examples)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^

error: Missing code example in this documentation
--> $DIR/lint-missing-doc-code-example.rs:37:3
|
LL | /// doc
| ^^^^^^^

error: aborting due to 2 previous errors