rustdoc: adopt to the new lint API

This commit is contained in:
Maybe Waffle 2022-09-16 19:07:20 +04:00
parent 7e90a41844
commit 6ecacf76bc
7 changed files with 61 additions and 78 deletions

View File

@ -404,12 +404,8 @@ pub(crate) fn run_global_ctxt(
tcx.struct_lint_node(
crate::lint::MISSING_CRATE_LEVEL_DOCS,
DocContext::as_local_hir_id(tcx, krate.module.item_id).unwrap(),
|lint| {
let mut diag =
lint.build("no documentation found for this crate's top-level module");
diag.help(&help);
diag.emit();
},
"no documentation found for this crate's top-level module",
|lint| lint.help(help),
);
}

View File

@ -813,11 +813,8 @@ impl<'tcx> ExtraInfo<'tcx> {
crate::lint::INVALID_CODEBLOCK_ATTRIBUTES,
hir_id,
self.sp,
|lint| {
let mut diag = lint.build(msg);
diag.help(help);
diag.emit();
},
msg,
|lint| lint.help(help),
);
}
}

View File

@ -71,16 +71,14 @@ impl<'a, 'tcx> DocVisitor for BareUrlsLinter<'a, 'tcx> {
let report_diag = |cx: &DocContext<'_>, msg: &str, url: &str, range: Range<usize>| {
let sp = super::source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs)
.unwrap_or_else(|| item.attr_span(cx.tcx));
cx.tcx.struct_span_lint_hir(crate::lint::BARE_URLS, hir_id, sp, |lint| {
lint.build(msg)
.note("bare URLs are not automatically turned into clickable links")
cx.tcx.struct_span_lint_hir(crate::lint::BARE_URLS, hir_id, sp, msg, |lint| {
lint.note("bare URLs are not automatically turned into clickable links")
.span_suggestion(
sp,
"use an automatic link instead",
format!("<{}>", url),
Applicability::MachineApplicable,
)
.emit();
});
};

View File

@ -2,7 +2,7 @@
use rustc_data_structures::sync::{Lock, Lrc};
use rustc_errors::{
emitter::Emitter, translation::Translate, Applicability, Diagnostic, Handler,
LazyFallbackBundle, LintDiagnosticBuilder,
LazyFallbackBundle,
};
use rustc_parse::parse_stream_from_source_str;
use rustc_session::parse::ParseSess;
@ -97,48 +97,10 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
None => (item.attr_span(self.cx.tcx), false),
};
// lambda that will use the lint to start a new diagnostic and add
// a suggestion to it when needed.
let diag_builder = |lint: LintDiagnosticBuilder<'_, ()>| {
let explanation = if is_ignore {
"`ignore` code blocks require valid Rust code for syntax highlighting; \
mark blocks that do not contain Rust code as text"
} else {
"mark blocks that do not contain Rust code as text"
};
let msg = if buffer.has_errors {
"could not parse code block as Rust code"
} else {
"Rust code block is empty"
};
let mut diag = lint.build(msg);
if precise_span {
if is_ignore {
// giving an accurate suggestion is hard because `ignore` might not have come first in the list.
// just give a `help` instead.
diag.span_help(
sp.from_inner(InnerSpan::new(0, 3)),
&format!("{}: ```text", explanation),
);
} else if empty_block {
diag.span_suggestion(
sp.from_inner(InnerSpan::new(0, 3)).shrink_to_hi(),
explanation,
"text",
Applicability::MachineApplicable,
);
}
} else if empty_block || is_ignore {
diag.help(&format!("{}: ```text", explanation));
}
// FIXME(#67563): Provide more context for these errors by displaying the spans inline.
for message in buffer.messages.iter() {
diag.note(message);
}
diag.emit();
let msg = if buffer.has_errors {
"could not parse code block as Rust code"
} else {
"Rust code block is empty"
};
// Finally build and emit the completed diagnostic.
@ -148,7 +110,42 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
crate::lint::INVALID_RUST_CODEBLOCKS,
hir_id,
sp,
diag_builder,
msg,
|lint| {
let explanation = if is_ignore {
"`ignore` code blocks require valid Rust code for syntax highlighting; \
mark blocks that do not contain Rust code as text"
} else {
"mark blocks that do not contain Rust code as text"
};
if precise_span {
if is_ignore {
// giving an accurate suggestion is hard because `ignore` might not have come first in the list.
// just give a `help` instead.
lint.span_help(
sp.from_inner(InnerSpan::new(0, 3)),
&format!("{}: ```text", explanation),
);
} else if empty_block {
lint.span_suggestion(
sp.from_inner(InnerSpan::new(0, 3)).shrink_to_hi(),
explanation,
"text",
Applicability::MachineApplicable,
);
}
} else if empty_block || is_ignore {
lint.help(&format!("{}: ```text", explanation));
}
// FIXME(#67563): Provide more context for these errors by displaying the spans inline.
for message in buffer.messages.iter() {
lint.note(message);
}
lint
},
);
}
}

View File

@ -125,9 +125,8 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item
crate::lint::MISSING_DOC_CODE_EXAMPLES,
hir_id,
sp,
|lint| {
lint.build("missing code example in this documentation").emit();
},
"missing code example in this documentation",
|lint| lint,
);
}
} else if tests.found_tests > 0
@ -137,9 +136,8 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item
crate::lint::PRIVATE_DOC_TESTS,
hir_id,
item.attr_span(cx.tcx),
|lint| {
lint.build("documentation test in private item").emit();
},
"documentation test in private item",
|lint| lint,
);
}
}

View File

@ -1609,9 +1609,7 @@ fn report_diagnostic(
let sp = item.attr_span(tcx);
tcx.struct_span_lint_hir(lint, hir_id, sp, |lint| {
let mut diag = lint.build(msg);
tcx.struct_span_lint_hir(lint, hir_id, sp, msg, |lint| {
let span =
super::source_span_for_markdown_range(tcx, dox, link_range, &item.attrs).map(|sp| {
if dox.as_bytes().get(link_range.start) == Some(&b'`')
@ -1624,7 +1622,7 @@ fn report_diagnostic(
});
if let Some(sp) = span {
diag.set_span(sp);
lint.set_span(sp);
} else {
// blah blah blah\nblah\nblah [blah] blah blah\nblah blah
// ^ ~~~~
@ -1634,7 +1632,7 @@ fn report_diagnostic(
let line = dox[last_new_line_offset..].lines().next().unwrap_or("");
// Print the line containing the `link_range` and manually mark it with '^'s.
diag.note(&format!(
lint.note(&format!(
"the link appears in this line:\n\n{line}\n\
{indicator: <before$}{indicator:^<found$}",
line = line,
@ -1644,9 +1642,9 @@ fn report_diagnostic(
));
}
decorate(&mut diag, span);
decorate(lint, span);
diag.emit();
lint
});
}

View File

@ -240,9 +240,8 @@ impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> {
Some(sp) => sp,
None => item.attr_span(tcx),
};
tcx.struct_span_lint_hir(crate::lint::INVALID_HTML_TAGS, hir_id, sp, |lint| {
tcx.struct_span_lint_hir(crate::lint::INVALID_HTML_TAGS, hir_id, sp, msg, |lint| {
use rustc_lint_defs::Applicability;
let mut diag = lint.build(msg);
// If a tag looks like `<this>`, it might actually be a generic.
// We don't try to detect stuff `<like, this>` because that's not valid HTML,
// and we don't try to detect stuff `<like this>` because that's not valid Rust.
@ -305,11 +304,10 @@ impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> {
if (generics_start > 0 && dox.as_bytes()[generics_start - 1] == b'<')
|| (generics_end < dox.len() && dox.as_bytes()[generics_end] == b'>')
{
diag.emit();
return;
return lint;
}
// multipart form is chosen here because ``Vec<i32>`` would be confusing.
diag.multipart_suggestion(
lint.multipart_suggestion(
"try marking as source code",
vec![
(generics_sp.shrink_to_lo(), String::from("`")),
@ -318,7 +316,8 @@ impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> {
Applicability::MaybeIncorrect,
);
}
diag.emit()
lint
});
};