- if buffer.has_errors || is_empty {
- let mut diag = if let Some(sp) = super::source_span_for_markdown_range(
- self.cx.tcx,
- &dox,
- &code_block.range,
- &item.attrs,
- ) {
- let (warning_message, suggest_using_text) = if buffer.has_errors {
- ("could not parse code block as Rust code", true)
- } else {
- ("Rust code block is empty", false)
- };
-
- let mut diag = self.cx.sess().struct_span_warn(sp, warning_message);
-
- if code_block.syntax.is_none() && code_block.is_fenced {
- let sp = sp.from_inner(InnerSpan::new(0, 3));
- diag.span_suggestion(
- sp,
- "mark blocks that do not contain Rust code as text",
- String::from("```text"),
- Applicability::MachineApplicable,
+ if !buffer.has_errors && !is_empty {
+ // No errors in a non-empty program.
+ return;
+ }
+
+ let local_id = match item.def_id.as_local() {
+ Some(id) => id,
+ // We don't need to check the syntax for other crates so returning
+ // without doing anything should not be a problem.
+ None => return,
+ };
+
+ let hir_id = self.cx.tcx.hir().local_def_id_to_hir_id(local_id);
+ let empty_block = code_block.syntax.is_none() && code_block.is_fenced;
+ let is_ignore = code_block.is_ignore;
+
+ // The span and whether it is precise or not.
+ let (sp, precise_span) = match super::source_span_for_markdown_range(
+ self.cx.tcx,
+ &dox,
+ &code_block.range,
+ &item.attrs,
+ ) {
+ Some(sp) => (sp, true),
+ 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),