Rollup merge of #105848 - lukas-code:backticks, r=GuillaumeGomez,jyn514,notriddle

rustdoc: Add a new lint for broken inline code

This patch adds `rustdoc::unescaped_backticks`, a new rustdoc lint that will detect broken inline code nodes.

The lint woks by finding stray backticks and with some heuristics tries to guess where the second backtick might be missing.

Here is how it looks:
```rust
#![warn(rustdoc::unescaped_backticks)]

/// `add(a, b) is the same as `add(b, a)`.
pub fn add(a: i32, b: i32) -> i32 { a + b }
```
```text
warning: unescaped backtick
 --> src/lib.rs:3:41
  |
3 | /// `add(a, b) is the same as `add(b, a)`.
  |                                         ^
  |
help: a previous inline code might be longer than expected
  |
3 | /// `add(a, b)` is the same as `add(b, a)`.
  |               +
help: if you meant to use a literal backtick, escape it
  |
3 | /// `add(a, b) is the same as `add(b, a)\`.
  |                                         +
```

If we can't get proper spans, for example if the doc comment comes from a macro expansion, we print the suggestion in help messages instead. Here's a [real-world example](https://docs.rs/tracing-subscriber/0.3.17/tracing_subscriber/layer/trait.Filter.html#method.max_level_hint):

```text
warning: unescaped backtick
    --> /tracing-subscriber-0.3.17/src/layer/mod.rs:1400:9
     |
1400 | /         /// Returns an optional hint of the highest [verbosity level][level] that
1401 | |         /// this `Filter` will enable.
1402 | |         ///
1403 | |         /// If this method returns a [`LevelFilter`], it will be used as a hint to
...    |
1427 | |         /// [`Interest`]: tracing_core::subscriber::Interest
1428 | |         /// [rebuild]: tracing_core::callsite::rebuild_interest_cache
     | |_____________________________________________________________________^
     |
     = help: a previous inline code might be longer than expected
              change: Therefore, if the `Filter will change the value returned by this
             to this: Therefore, if the `Filter` will change the value returned by this
     = help: if you meant to use a literal backtick, escape it
              change: [`rebuild_interest_cache`][rebuild] is called after the value of the max
             to this: [`rebuild_interest_cache\`][rebuild] is called after the value of the max
```

You can find more examples [here](https://gist.github.com/lukas-code/7678ddf5c608aee97b3a669de80d3465).

A limitation of the current implementation is, that it cannot suggest removing misplaced backticks, for example [here](https://docs.rs/tikv-jemalloc-sys/0.5.3+5.3.0-patched/tikv_jemalloc_sys/fn.mallctl.html).

The lint is allowed by default ~~and nightly-only~~ for now, ~~but without a feature gate. This is similar to how `rustdoc::invalid_html_tags` and `rustdoc::bare_urls` were handled.~~
This commit is contained in:
Matthias Krüger 2023-04-29 15:51:15 +02:00 committed by GitHub
commit 825bc606f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 1777 additions and 7 deletions

View File

@ -374,3 +374,41 @@ warning: this URL is not a hyperlink
warning: 2 warnings emitted
```
## `unescaped_backticks`
This lint is **allowed by default**. It detects backticks (\`) that are not escaped.
This usually means broken inline code. For example:
```rust
#![warn(rustdoc::unescaped_backticks)]
/// `add(a, b) is the same as `add(b, a)`.
pub fn add(a: i32, b: i32) -> i32 { a + b }
```
Which will give:
```text
warning: unescaped backtick
--> src/lib.rs:3:41
|
3 | /// `add(a, b) is the same as `add(b, a)`.
| ^
|
note: the lint level is defined here
--> src/lib.rs:1:9
|
1 | #![warn(rustdoc::unescaped_backticks)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: a previous inline code might be longer than expected
|
3 | /// `add(a, b)` is the same as `add(b, a)`.
| +
help: if you meant to use a literal backtick, escape it
|
3 | /// `add(a, b) is the same as `add(b, a)\`.
| +
warning: 1 warning emitted
```

View File

@ -7,14 +7,15 @@
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(drain_filter)]
#![feature(let_chains)]
#![feature(test)]
#![feature(never_type)]
#![feature(lazy_cell)]
#![feature(type_ascription)]
#![feature(iter_intersperse)]
#![feature(type_alias_impl_trait)]
#![feature(impl_trait_in_assoc_type)]
#![feature(iter_intersperse)]
#![feature(lazy_cell)]
#![feature(let_chains)]
#![feature(never_type)]
#![feature(round_char_boundary)]
#![feature(test)]
#![feature(type_alias_impl_trait)]
#![feature(type_ascription)]
#![recursion_limit = "256"]
#![warn(rustc::internal)]
#![allow(clippy::collapsible_if, clippy::collapsible_else_if)]

View File

@ -174,6 +174,17 @@ declare_rustdoc_lint! {
"codeblock could not be parsed as valid Rust or is empty"
}
declare_rustdoc_lint! {
/// The `unescaped_backticks` lint detects unescaped backticks (\`), which usually
/// mean broken inline code. This is a `rustdoc` only lint, see the documentation
/// in the [rustdoc book].
///
/// [rustdoc book]: ../../../rustdoc/lints.html#unescaped_backticks
UNESCAPED_BACKTICKS,
Allow,
"detects unescaped backticks in doc comments"
}
pub(crate) static RUSTDOC_LINTS: Lazy<Vec<&'static Lint>> = Lazy::new(|| {
vec![
BROKEN_INTRA_DOC_LINKS,
@ -185,6 +196,7 @@ pub(crate) static RUSTDOC_LINTS: Lazy<Vec<&'static Lint>> = Lazy::new(|| {
INVALID_HTML_TAGS,
BARE_URLS,
MISSING_CRATE_LEVEL_DOCS,
UNESCAPED_BACKTICKS,
]
});

View File

@ -4,6 +4,7 @@
mod bare_urls;
mod check_code_block_syntax;
mod html_tags;
mod unescaped_backticks;
use super::Pass;
use crate::clean::*;
@ -27,6 +28,7 @@ impl<'a, 'tcx> DocVisitor for Linter<'a, 'tcx> {
bare_urls::visit_item(self.cx, item);
check_code_block_syntax::visit_item(self.cx, item);
html_tags::visit_item(self.cx, item);
unescaped_backticks::visit_item(self.cx, item);
self.visit_item_recur(item)
}

View File

@ -0,0 +1,416 @@
//! Detects unescaped backticks (\`) in doc comments.
use crate::clean::Item;
use crate::core::DocContext;
use crate::html::markdown::main_body_opts;
use crate::passes::source_span_for_markdown_range;
use pulldown_cmark::{BrokenLink, Event, Parser};
use rustc_errors::DiagnosticBuilder;
use rustc_lint_defs::Applicability;
use std::ops::Range;
pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
let tcx = cx.tcx;
let Some(hir_id) = DocContext::as_local_hir_id(tcx, item.item_id) else {
// If non-local, no need to check anything.
return;
};
let dox = item.attrs.collapsed_doc_value().unwrap_or_default();
if dox.is_empty() {
return;
}
let link_names = item.link_names(&cx.cache);
let mut replacer = |broken_link: BrokenLink<'_>| {
link_names
.iter()
.find(|link| *link.original_text == *broken_link.reference)
.map(|link| ((*link.href).into(), (*link.new_text).into()))
};
let parser = Parser::new_with_broken_link_callback(&dox, main_body_opts(), Some(&mut replacer))
.into_offset_iter();
let mut element_stack = Vec::new();
let mut prev_text_end = 0;
for (event, event_range) in parser {
match event {
Event::Start(_) => {
element_stack.push(Element::new(event_range));
}
Event::End(_) => {
let element = element_stack.pop().unwrap();
let Some(backtick_index) = element.backtick_index else {
continue;
};
// If we can't get a span of the backtick, because it is in a `#[doc = ""]` attribute,
// use the span of the entire attribute as a fallback.
let span = source_span_for_markdown_range(
tcx,
&dox,
&(backtick_index..backtick_index + 1),
&item.attrs,
)
.unwrap_or_else(|| item.attr_span(tcx));
cx.tcx.struct_span_lint_hir(crate::lint::UNESCAPED_BACKTICKS, hir_id, span, "unescaped backtick", |lint| {
let mut help_emitted = false;
match element.prev_code_guess {
PrevCodeGuess::None => {}
PrevCodeGuess::Start { guess, .. } => {
// "foo` `bar`" -> "`foo` `bar`"
if let Some(suggest_index) = clamp_start(guess, &element.suggestible_ranges)
&& can_suggest_backtick(&dox, suggest_index)
{
suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "the opening backtick of a previous inline code may be missing");
help_emitted = true;
}
}
PrevCodeGuess::End { guess, .. } => {
// "`foo `bar`" -> "`foo` `bar`"
// Don't `clamp_end` here, because the suggestion is guaranteed to be inside
// an inline code node and we intentionally "break" the inline code here.
let suggest_index = guess;
if can_suggest_backtick(&dox, suggest_index) {
suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "a previous inline code might be longer than expected");
help_emitted = true;
}
}
}
if !element.prev_code_guess.is_confident() {
// "`foo` bar`" -> "`foo` `bar`"
if let Some(guess) = guess_start_of_code(&dox, element.element_range.start..backtick_index)
&& let Some(suggest_index) = clamp_start(guess, &element.suggestible_ranges)
&& can_suggest_backtick(&dox, suggest_index)
{
suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "the opening backtick of an inline code may be missing");
help_emitted = true;
}
// "`foo` `bar" -> "`foo` `bar`"
// Don't suggest closing backtick after single trailing char,
// if we already suggested opening backtick. For example:
// "foo`." -> "`foo`." or "foo`s" -> "`foo`s".
if let Some(guess) = guess_end_of_code(&dox, backtick_index + 1..element.element_range.end)
&& let Some(suggest_index) = clamp_end(guess, &element.suggestible_ranges)
&& can_suggest_backtick(&dox, suggest_index)
&& (!help_emitted || suggest_index - backtick_index > 2)
{
suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "the closing backtick of an inline code may be missing");
help_emitted = true;
}
}
if !help_emitted {
lint.help("the opening or closing backtick of an inline code may be missing");
}
suggest_insertion(cx, item, &dox, lint, backtick_index, '\\', "if you meant to use a literal backtick, escape it");
lint
});
}
Event::Code(_) => {
let element = element_stack
.last_mut()
.expect("expected inline code node to be inside of an element");
assert!(
event_range.start >= element.element_range.start
&& event_range.end <= element.element_range.end
);
// This inline code might be longer than it's supposed to be.
// Only check single backtick inline code for now.
if !element.prev_code_guess.is_confident()
&& dox.as_bytes().get(event_range.start) == Some(&b'`')
&& dox.as_bytes().get(event_range.start + 1) != Some(&b'`')
{
let range_inside = event_range.start + 1..event_range.end - 1;
let text_inside = &dox[range_inside.clone()];
let is_confident = text_inside.starts_with(char::is_whitespace)
|| text_inside.ends_with(char::is_whitespace);
if let Some(guess) = guess_end_of_code(&dox, range_inside) {
// Find earlier end of code.
element.prev_code_guess = PrevCodeGuess::End { guess, is_confident };
} else {
// Find alternate start of code.
let range_before = element.element_range.start..event_range.start;
if let Some(guess) = guess_start_of_code(&dox, range_before) {
element.prev_code_guess = PrevCodeGuess::Start { guess, is_confident };
}
}
}
}
Event::Text(text) => {
let element = element_stack
.last_mut()
.expect("expected inline text node to be inside of an element");
assert!(
event_range.start >= element.element_range.start
&& event_range.end <= element.element_range.end
);
// The first char is escaped if the prev char is \ and not part of a text node.
let is_escaped = prev_text_end < event_range.start
&& dox.as_bytes()[event_range.start - 1] == b'\\';
// Don't lint backslash-escaped (\`) or html-escaped (&#96;) backticks.
if *text == *"`" && !is_escaped && *text == dox[event_range.clone()] {
// We found a stray backtick.
assert!(
element.backtick_index.is_none(),
"expected at most one unescaped backtick per element",
);
element.backtick_index = Some(event_range.start);
}
prev_text_end = event_range.end;
if is_escaped {
// Ensure that we suggest "`\x" and not "\`x".
element.suggestible_ranges.push(event_range.start - 1..event_range.end);
} else {
element.suggestible_ranges.push(event_range);
}
}
_ => {}
}
}
}
/// A previous inline code node, that looks wrong.
///
/// `guess` is the position, where we want to suggest a \` and the guess `is_confident` if an
/// inline code starts or ends with a whitespace.
#[derive(Debug)]
enum PrevCodeGuess {
None,
/// Missing \` at start.
///
/// ```markdown
/// foo` `bar`
/// ```
Start {
guess: usize,
is_confident: bool,
},
/// Missing \` at end.
///
/// ```markdown
/// `foo `bar`
/// ```
End {
guess: usize,
is_confident: bool,
},
}
impl PrevCodeGuess {
fn is_confident(&self) -> bool {
match *self {
PrevCodeGuess::None => false,
PrevCodeGuess::Start { is_confident, .. } | PrevCodeGuess::End { is_confident, .. } => {
is_confident
}
}
}
}
/// A markdown [tagged element], which may or may not contain an unescaped backtick.
///
/// [tagged element]: https://docs.rs/pulldown-cmark/0.9/pulldown_cmark/enum.Tag.html
#[derive(Debug)]
struct Element {
/// The full range (span) of the element in the doc string.
element_range: Range<usize>,
/// The ranges where we're allowed to put backticks.
/// This is used to prevent breaking markdown elements like links or lists.
suggestible_ranges: Vec<Range<usize>>,
/// The unescaped backtick.
backtick_index: Option<usize>,
/// Suggest a different start or end of an inline code.
prev_code_guess: PrevCodeGuess,
}
impl Element {
const fn new(element_range: Range<usize>) -> Self {
Self {
element_range,
suggestible_ranges: Vec::new(),
backtick_index: None,
prev_code_guess: PrevCodeGuess::None,
}
}
}
/// Given a potentially unclosed inline code, attempt to find the start.
fn guess_start_of_code(dox: &str, range: Range<usize>) -> Option<usize> {
assert!(dox.as_bytes()[range.end] == b'`');
let mut braces = 0;
let mut guess = 0;
for (idx, ch) in dox[range.clone()].char_indices().rev() {
match ch {
')' | ']' | '}' => braces += 1,
'(' | '[' | '{' => {
if braces == 0 {
guess = idx + 1;
break;
}
braces -= 1;
}
ch if ch.is_whitespace() && braces == 0 => {
guess = idx + 1;
break;
}
_ => (),
}
}
guess += range.start;
// Don't suggest empty inline code or duplicate backticks.
can_suggest_backtick(dox, guess).then_some(guess)
}
/// Given a potentially unclosed inline code, attempt to find the end.
fn guess_end_of_code(dox: &str, range: Range<usize>) -> Option<usize> {
// Punctuation that should be outside of the inline code.
const TRAILING_PUNCTUATION: &[u8] = b".,";
assert!(dox.as_bytes()[range.start - 1] == b'`');
let text = dox[range.clone()].trim_end();
let mut braces = 0;
let mut guess = text.len();
for (idx, ch) in text.char_indices() {
match ch {
'(' | '[' | '{' => braces += 1,
')' | ']' | '}' => {
if braces == 0 {
guess = idx;
break;
}
braces -= 1;
}
ch if ch.is_whitespace() && braces == 0 => {
guess = idx;
break;
}
_ => (),
}
}
// Strip a single trailing punctuation.
if guess >= 1
&& TRAILING_PUNCTUATION.contains(&text.as_bytes()[guess - 1])
&& (guess < 2 || !TRAILING_PUNCTUATION.contains(&text.as_bytes()[guess - 2]))
{
guess -= 1;
}
guess += range.start;
// Don't suggest empty inline code or duplicate backticks.
can_suggest_backtick(dox, guess).then_some(guess)
}
/// Returns whether inserting a backtick at `dox[index]` will not produce double backticks.
fn can_suggest_backtick(dox: &str, index: usize) -> bool {
(index == 0 || dox.as_bytes()[index - 1] != b'`')
&& (index == dox.len() || dox.as_bytes()[index] != b'`')
}
/// Increase the index until it is inside or one past the end of one of the ranges.
///
/// The ranges must be sorted for this to work correctly.
fn clamp_start(index: usize, ranges: &[Range<usize>]) -> Option<usize> {
for range in ranges {
if range.start >= index {
return Some(range.start);
}
if index <= range.end {
return Some(index);
}
}
None
}
/// Decrease the index until it is inside or one past the end of one of the ranges.
///
/// The ranges must be sorted for this to work correctly.
fn clamp_end(index: usize, ranges: &[Range<usize>]) -> Option<usize> {
for range in ranges.iter().rev() {
if range.end <= index {
return Some(range.end);
}
if index >= range.start {
return Some(index);
}
}
None
}
/// Try to emit a span suggestion and fall back to help messages if we can't find a suitable span.
///
/// This helps finding backticks in huge macro-generated docs.
fn suggest_insertion(
cx: &DocContext<'_>,
item: &Item,
dox: &str,
lint: &mut DiagnosticBuilder<'_, ()>,
insert_index: usize,
suggestion: char,
message: &str,
) {
/// Maximum bytes of context to show around the insertion.
const CONTEXT_MAX_LEN: usize = 80;
if let Some(span) =
source_span_for_markdown_range(cx.tcx, &dox, &(insert_index..insert_index), &item.attrs)
{
lint.span_suggestion(span, message, suggestion, Applicability::MaybeIncorrect);
} else {
let line_start = dox[..insert_index].rfind('\n').map_or(0, |idx| idx + 1);
let line_end = dox[insert_index..].find('\n').map_or(dox.len(), |idx| idx + insert_index);
let context_before_max_len = if insert_index - line_start < CONTEXT_MAX_LEN / 2 {
insert_index - line_start
} else if line_end - insert_index < CONTEXT_MAX_LEN / 2 {
CONTEXT_MAX_LEN - (line_end - insert_index)
} else {
CONTEXT_MAX_LEN / 2
};
let context_after_max_len = CONTEXT_MAX_LEN - context_before_max_len;
let (prefix, context_start) = if insert_index - line_start <= context_before_max_len {
("", line_start)
} else {
("...", dox.ceil_char_boundary(insert_index - context_before_max_len))
};
let (suffix, context_end) = if line_end - insert_index <= context_after_max_len {
("", line_end)
} else {
("...", dox.floor_char_boundary(insert_index + context_after_max_len))
};
let context_full = &dox[context_start..context_end].trim_end();
let context_before = &dox[context_start..insert_index];
let context_after = &dox[insert_index..context_end].trim_end();
lint.help(format!(
"{message}\n change: {prefix}{context_full}{suffix}\nto this: {prefix}{context_before}{suggestion}{context_after}{suffix}"
));
}
}

View File

@ -0,0 +1,342 @@
#![deny(rustdoc::unescaped_backticks)]
#![allow(rustdoc::broken_intra_doc_links)]
#![allow(rustdoc::invalid_html_tags)]
///
pub fn empty() {}
#[doc = ""]
pub fn empty2() {}
/// `
//~^ ERROR unescaped backtick
pub fn single() {}
/// \`
pub fn escaped() {}
/// \\`
//~^ ERROR unescaped backtick
pub fn not_escaped() {}
/// \\\`
pub fn not_not_escaped() {}
/// [`link1]
//~^ ERROR unescaped backtick
pub fn link1() {}
/// [link2`]
//~^ ERROR unescaped backtick
pub fn link2() {}
/// [`link_long](link_long)
//~^ ERROR unescaped backtick
pub fn link_long() {}
/// [`broken-link]
//~^ ERROR unescaped backtick
pub fn broken_link() {}
/// <xx:`>
pub fn url() {}
/// <x:`>
//~^ ERROR unescaped backtick
pub fn not_url() {}
/// <h1>`</h1>
pub fn html_tag() {}
/// &#96;
pub fn html_escape() {}
/// 🦀`🦀
//~^ ERROR unescaped backtick
pub fn unicode() {}
/// `foo(
//~^ ERROR unescaped backtick
///
/// paragraph
pub fn paragraph() {}
/// `foo `bar`
//~^ ERROR unescaped backtick
///
/// paragraph
pub fn paragraph2() {}
/// `foo(
//~^ ERROR unescaped backtick
/// not paragraph
pub fn not_paragraph() {}
/// Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`.
//~^ ERROR unescaped backtick
///
/// You could use this function to add 42 to a number `n` (add(n, 42)`),
/// or even to add a number `n` to 42 (`add(42, b)`)!
//~^ ERROR unescaped backtick
pub fn add1(a: i32, b: i32) -> i32 { a + b }
/// Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`.
//~^ ERROR unescaped backtick
///
/// You could use this function to add 42 to a number `n` (`add(n, 42)),
/// or even to add a number `n` to 42 (`add(42, n)`)!
//~^ ERROR unescaped backtick
pub fn add2(a: i32, b: i32) -> i32 { a + b }
/// Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`.
//~^ ERROR unescaped backtick
///
/// You could use this function to add 42 to a number `n` (`add(n, 42)`),
/// or even to add a number `n` to 42 (add(42, n)`)!
//~^ ERROR unescaped backtick
pub fn add3(a: i32, b: i32) -> i32 { a + b }
/// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a).
//~^ ERROR unescaped backtick
///
/// You could use this function to add 42 to a number `n` (`add(n, 42)),
/// or even to add a number `n` to 42 (`add(42, n)`)!
//~^ ERROR unescaped backtick
pub fn add4(a: i32, b: i32) -> i32 { a + b }
#[doc = "`"]
//~^ ERROR unescaped backtick
pub fn attr() {}
#[doc = concat!("\\", "`")]
pub fn attr_escaped() {}
#[doc = concat!("\\\\", "`")]
//~^ ERROR unescaped backtick
pub fn attr_not_escaped() {}
#[doc = "Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."]
//~^ ERROR unescaped backtick
pub fn attr_add1(a: i32, b: i32) -> i32 { a + b }
#[doc = "Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."]
//~^ ERROR unescaped backtick
pub fn attr_add2(a: i32, b: i32) -> i32 { a + b }
#[doc = "Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."]
//~^ ERROR unescaped backtick
pub fn attr_add3(a: i32, b: i32) -> i32 { a + b }
#[doc = "Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."]
//~^ ERROR unescaped backtick
pub fn attr_add4(a: i32, b: i32) -> i32 { a + b }
/// ``double backticks``
/// `foo
//~^ ERROR unescaped backtick
pub fn double_backticks() {}
/// # `(heading
//~^ ERROR unescaped backtick
/// ## heading2)`
//~^ ERROR unescaped backtick
///
/// multi `(
//~^ ERROR unescaped backtick
/// line
/// ) heading
/// =
///
/// para)`(graph
//~^ ERROR unescaped backtick
///
/// para)`(graph2
//~^ ERROR unescaped backtick
///
/// 1. foo)`
//~^ ERROR unescaped backtick
/// 2. `(bar
//~^ ERROR unescaped backtick
/// * baz)`
//~^ ERROR unescaped backtick
/// * `(quux
//~^ ERROR unescaped backtick
///
/// `#![this_is_actually_an_image(and(not), an = "attribute")]
//~^ ERROR unescaped backtick
///
/// #![this_is_actually_an_image(and(not), an = "attribute")]`
//~^ ERROR unescaped backtick
///
/// [this_is_actually_an_image(and(not), an = "attribute")]: `.png
///
/// | `table( | )head` |
//~^ ERROR unescaped backtick
//~| ERROR unescaped backtick
/// |---------|--------|
/// | table`( | )`body |
//~^ ERROR unescaped backtick
//~| ERROR unescaped backtick
pub fn complicated_markdown() {}
/// The `custom_mir` attribute tells the compiler to treat the function as being custom MIR. This
/// attribute only works on functions - there is no way to insert custom MIR into the middle of
/// another function. The `dialect` and `phase` parameters indicate which [version of MIR][dialect
/// docs] you are inserting here. Generally you'll want to use `#![custom_mir(dialect = "built")]`
/// if you want your MIR to be modified by the full MIR pipeline, or `#![custom_mir(dialect =
//~^ ERROR unescaped backtick
/// "runtime", phase = "optimized")] if you don't.
pub mod mir {}
pub mod rustc {
/// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg to
//~^ ERROR unescaped backtick
/// ensure it gets used.
pub fn ty_error_with_message() {}
pub struct WhereClause {
/// `true` if we ate a `where` token: this can happen
/// if we parsed no predicates (e.g. `struct Foo where {}
/// This allows us to accurately pretty-print
/// in `nt_to_tokenstream`
//~^ ERROR unescaped backtick
pub has_where_token: bool,
}
/// A symbol is an interned or gensymed string. The use of `newtype_index!` means
/// that `Option<Symbol>` only takes up 4 bytes, because `newtype_index! reserves
//~^ ERROR unescaped backtick
/// the last 256 values for tagging purposes.
pub struct Symbol();
/// It is equivalent to `OpenOptions::new()` but allows you to write more
/// readable code. Instead of `OpenOptions::new().read(true).open("foo.txt")`
/// you can write `File::with_options().read(true).open("foo.txt"). This
/// also avoids the need to import `OpenOptions`.
//~^ ERROR unescaped backtick
pub fn with_options() {}
/// Subtracts `set from `row`. `set` can be either `BitSet` or
/// `HybridBitSet`. Has no effect if `row` does not exist.
//~^ ERROR unescaped backtick
///
/// Returns true if the row was changed.
pub fn subtract_row() {}
pub mod assert_module_sources {
//! The reason that we use `cfg=...` and not `#[cfg_attr]` is so that
//! the HIR doesn't change as a result of the annotations, which might
//! perturb the reuse results.
//!
//! `#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")]
//~^ ERROR unescaped backtick
//! allows for doing a more fine-grained check to see if pre- or post-lto data
//! was re-used.
/// `cfg=...
//~^ ERROR unescaped backtick
pub fn foo() {}
/// `cfg=... and not `#[cfg_attr]`
//~^ ERROR unescaped backtick
pub fn bar() {}
}
/// Conceptually, this is like a `Vec<Vec<RWU>>`. But the number of
/// RWU`s can get very large, so it uses a more compact representation.
//~^ ERROR unescaped backtick
pub struct RWUTable {}
/// Like [Self::canonicalize_query], but preserves distinct universes. For
/// example, canonicalizing `&'?0: Trait<'?1>`, where `'?0` is in `U1` and
/// `'?1` is in `U3` would be canonicalized to have ?0` in `U1` and `'?1`
/// in `U2`.
//~^ ERROR unescaped backtick
///
/// This is used for Chalk integration.
pub fn canonicalize_query_preserving_universes() {}
/// Note that we used to return `Error` here, but that was quite
/// dubious -- the premise was that an error would *eventually* be
/// reported, when the obligation was processed. But in general once
/// you see an `Error` you are supposed to be able to assume that an
/// error *has been* reported, so that you can take whatever heuristic
/// paths you want to take. To make things worse, it was possible for
/// cycles to arise, where you basically had a setup like `<MyType<$0>
/// as Trait>::Foo == $0`. Here, normalizing `<MyType<$0> as
/// Trait>::Foo> to `[type error]` would lead to an obligation of
/// `<MyType<[type error]> as Trait>::Foo`. We are supposed to report
/// an error for this obligation, but we legitimately should not,
/// because it contains `[type error]`. Yuck! (See issue #29857 for
//~^ ERROR unescaped backtick
/// one case where this arose.)
pub fn normalize_to_error() {}
/// you don't want to cache that `B: AutoTrait` or `A: AutoTrait`
/// is `EvaluatedToOk`; this is because they were only considered
/// ok on the premise that if `A: AutoTrait` held, but we indeed
/// encountered a problem (later on) with `A: AutoTrait. So we
/// currently set a flag on the stack node for `B: AutoTrait` (as
/// well as the second instance of `A: AutoTrait`) to suppress
//~^ ERROR unescaped backtick
/// caching.
pub struct TraitObligationStack;
/// Extend `scc` so that it can outlive some placeholder region
/// from a universe it can't name; at present, the only way for
/// this to be true is if `scc` outlives `'static`. This is
/// actually stricter than necessary: ideally, we'd support bounds
/// like `for<'a: 'b`>` that might then allow us to approximate
/// `'a` with `'b` and not `'static`. But it will have to do for
//~^ ERROR unescaped backtick
/// now.
pub fn add_incompatible_universe(){}
}
/// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
/// which returns an `Option<Dispatch>`. If all [`Dispatch`] clones that point
/// at the `Subscriber` have been dropped, [`WeakDispatch::upgrade`] will return
/// `None`. Otherwise, it will return `Some(Dispatch)`.
//~^ ERROR unescaped backtick
///
/// Returns some reference to this `[`Subscriber`] value if it is of type `T`,
/// or `None` if it isn't.
//~^ ERROR unescaped backtick
///
/// Called before the filtered [`Layer]'s [`on_event`], to determine if
/// `on_event` should be called.
//~^ ERROR unescaped backtick
///
/// Therefore, if the `Filter will change the value returned by this
/// method, it is responsible for ensuring that
/// [`rebuild_interest_cache`][rebuild] is called after the value of the max
//~^ ERROR unescaped backtick
/// level changes.
pub mod tracing {}
macro_rules! id {
($($tt:tt)*) => { $($tt)* }
}
id! {
/// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
//~^ ERROR unescaped backtick
//~| ERROR unescaped backtick
//~| ERROR unescaped backtick
//~| ERROR unescaped backtick
/// which returns an `Option<Dispatch>`. If all [`Dispatch`] clones that point
/// at the `Subscriber` have been dropped, [`WeakDispatch::upgrade`] will return
/// `None`. Otherwise, it will return `Some(Dispatch)`.
///
/// Returns some reference to this `[`Subscriber`] value if it is of type `T`,
/// or `None` if it isn't.
///
/// Called before the filtered [`Layer]'s [`on_event`], to determine if
/// `on_event` should be called.
///
/// Therefore, if the `Filter will change the value returned by this
/// method, it is responsible for ensuring that
/// [`rebuild_interest_cache`][rebuild] is called after the value of the max
/// level changes.
pub mod tracing_macro {}
}

View File

@ -0,0 +1,959 @@
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:186:70
|
LL | /// if you want your MIR to be modified by the full MIR pipeline, or `#![custom_mir(dialect =
| ^
|
note: the lint level is defined here
--> $DIR/unescaped_backticks.rs:1:9
|
LL | #![deny(rustdoc::unescaped_backticks)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the closing backtick of an inline code may be missing
|
LL | /// "runtime", phase = "optimized")]` if you don't.
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// if you want your MIR to be modified by the full MIR pipeline, or \`#![custom_mir(dialect =
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:231:13
|
LL | //! `#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")]
| ^
|
help: the closing backtick of an inline code may be missing
|
LL | //! `#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")]`
| +
help: if you meant to use a literal backtick, escape it
|
LL | //! \`#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")]
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:236:13
|
LL | /// `cfg=...
| ^
|
help: the closing backtick of an inline code may be missing
|
LL | /// `cfg=...`
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// \`cfg=...
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:240:42
|
LL | /// `cfg=... and not `#[cfg_attr]`
| ^
|
help: a previous inline code might be longer than expected
|
LL | /// `cfg=...` and not `#[cfg_attr]`
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// `cfg=... and not `#[cfg_attr]\`
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:192:91
|
LL | /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg to
| ^
|
help: the closing backtick of an inline code may be missing
|
LL | /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg` to
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given \`msg to
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:201:34
|
LL | /// in `nt_to_tokenstream`
| ^
|
help: a previous inline code might be longer than expected
|
LL | /// if we parsed no predicates (e.g. `struct` Foo where {}
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// in `nt_to_tokenstream\`
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:207:62
|
LL | /// that `Option<Symbol>` only takes up 4 bytes, because `newtype_index! reserves
| ^
|
help: the closing backtick of an inline code may be missing
|
LL | /// that `Option<Symbol>` only takes up 4 bytes, because `newtype_index!` reserves
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// that `Option<Symbol>` only takes up 4 bytes, because \`newtype_index! reserves
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:215:52
|
LL | /// also avoids the need to import `OpenOptions`.
| ^
|
help: a previous inline code might be longer than expected
|
LL | /// you can write `File::with_options().read(true).open("foo.txt")`. This
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// also avoids the need to import `OpenOptions\`.
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:220:46
|
LL | /// `HybridBitSet`. Has no effect if `row` does not exist.
| ^
|
help: a previous inline code might be longer than expected
|
LL | /// Subtracts `set` from `row`. `set` can be either `BitSet` or
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// `HybridBitSet`. Has no effect if `row\` does not exist.
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:246:12
|
LL | /// RWU`s can get very large, so it uses a more compact representation.
| ^
|
help: the opening backtick of an inline code may be missing
|
LL | /// `RWU`s can get very large, so it uses a more compact representation.
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// RWU\`s can get very large, so it uses a more compact representation.
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:253:15
|
LL | /// in `U2`.
| ^
|
help: the opening backtick of a previous inline code may be missing
|
LL | /// `'?1` is in `U3` would be canonicalized to have `?0` in `U1` and `'?1`
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// in `U2\`.
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:270:42
|
LL | /// because it contains `[type error]`. Yuck! (See issue #29857 for
| ^
|
help: a previous inline code might be longer than expected
|
LL | /// as Trait>::Foo == $0`. Here, normalizing `<MyType<$0>` as
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// because it contains `[type error]\`. Yuck! (See issue #29857 for
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:280:53
|
LL | /// well as the second instance of `A: AutoTrait`) to suppress
| ^
|
help: a previous inline code might be longer than expected
|
LL | /// encountered a problem (later on) with `A:` AutoTrait. So we
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// well as the second instance of `A: AutoTrait\`) to suppress
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:290:40
|
LL | /// `'a` with `'b` and not `'static`. But it will have to do for
| ^
|
= help: the opening or closing backtick of an inline code may be missing
help: if you meant to use a literal backtick, escape it
|
LL | /// `'a` with `'b` and not `'static\`. But it will have to do for
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:299:54
|
LL | /// `None`. Otherwise, it will return `Some(Dispatch)`.
| ^
|
help: the opening backtick of a previous inline code may be missing
|
LL | /// The `Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// `None`. Otherwise, it will return `Some(Dispatch)\`.
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:303:13
|
LL | /// or `None` if it isn't.
| ^
|
= help: the opening or closing backtick of an inline code may be missing
help: if you meant to use a literal backtick, escape it
|
LL | /// or `None\` if it isn't.
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:307:14
|
LL | /// `on_event` should be called.
| ^
|
help: a previous inline code might be longer than expected
|
LL | /// Called before the filtered [`Layer`]'s [`on_event`], to determine if
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// `on_event\` should be called.
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:312:29
|
LL | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max
| ^
|
help: a previous inline code might be longer than expected
|
LL | /// Therefore, if the `Filter` will change the value returned by this
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// [`rebuild_interest_cache\`][rebuild] is called after the value of the max
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:322:5
|
LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
LL | |
LL | |
LL | |
... |
LL | | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max
LL | | /// level changes.
| |______________________^
|
= help: the opening backtick of a previous inline code may be missing
change: The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
to this: The `Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
= help: if you meant to use a literal backtick, escape it
change: `None`. Otherwise, it will return `Some(Dispatch)`.
to this: `None`. Otherwise, it will return `Some(Dispatch)\`.
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:322:5
|
LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
LL | |
LL | |
LL | |
... |
LL | | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max
LL | | /// level changes.
| |______________________^
|
= help: the opening or closing backtick of an inline code may be missing
= help: if you meant to use a literal backtick, escape it
change: or `None` if it isn't.
to this: or `None\` if it isn't.
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:322:5
|
LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
LL | |
LL | |
LL | |
... |
LL | | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max
LL | | /// level changes.
| |______________________^
|
= help: a previous inline code might be longer than expected
change: Called before the filtered [`Layer]'s [`on_event`], to determine if
to this: Called before the filtered [`Layer`]'s [`on_event`], to determine if
= help: if you meant to use a literal backtick, escape it
change: `on_event` should be called.
to this: `on_event\` should be called.
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:322:5
|
LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
LL | |
LL | |
LL | |
... |
LL | | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max
LL | | /// level changes.
| |______________________^
|
= help: a previous inline code might be longer than expected
change: Therefore, if the `Filter will change the value returned by this
to this: Therefore, if the `Filter` will change the value returned by this
= help: if you meant to use a literal backtick, escape it
change: [`rebuild_interest_cache`][rebuild] is called after the value of the max
to this: [`rebuild_interest_cache\`][rebuild] is called after the value of the max
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:11:5
|
LL | /// `
| ^
|
= help: the opening or closing backtick of an inline code may be missing
help: if you meant to use a literal backtick, escape it
|
LL | /// \`
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:18:7
|
LL | /// \`
| ^
|
help: the opening backtick of an inline code may be missing
|
LL | /// `\`
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// \\`
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:25:6
|
LL | /// [`link1]
| ^
|
help: the closing backtick of an inline code may be missing
|
LL | /// [`link1`]
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// [\`link1]
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:29:11
|
LL | /// [link2`]
| ^
|
help: the opening backtick of an inline code may be missing
|
LL | /// [`link2`]
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// [link2\`]
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:33:6
|
LL | /// [`link_long](link_long)
| ^
|
help: the closing backtick of an inline code may be missing
|
LL | /// [`link_long`](link_long)
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// [\`link_long](link_long)
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:37:6
|
LL | /// [`broken-link]
| ^
|
help: the closing backtick of an inline code may be missing
|
LL | /// [`broken-link`]
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// [\`broken-link]
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:44:8
|
LL | /// <x:`>
| ^
|
help: the opening backtick of an inline code may be missing
|
LL | /// `<x:`>
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// <x:\`>
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:54:6
|
LL | /// 🦀`🦀
| ^
|
help: the opening backtick of an inline code may be missing
|
LL | /// `🦀`🦀
| +
help: the closing backtick of an inline code may be missing
|
LL | /// 🦀`🦀`
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// 🦀\`🦀
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:58:5
|
LL | /// `foo(
| ^
|
help: the closing backtick of an inline code may be missing
|
LL | /// `foo(`
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// \`foo(
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:64:14
|
LL | /// `foo `bar`
| ^
|
help: a previous inline code might be longer than expected
|
LL | /// `foo` `bar`
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// `foo `bar\`
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:70:5
|
LL | /// `foo(
| ^
|
help: the closing backtick of an inline code may be missing
|
LL | /// not paragraph`
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// \`foo(
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:75:83
|
LL | /// Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`.
| ^
|
help: the opening backtick of a previous inline code may be missing
|
LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// Addition is commutative, which means that add(a, b)` is the same as `add(b, a)\`.
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:79:51
|
LL | /// or even to add a number `n` to 42 (`add(42, b)`)!
| ^
|
help: the opening backtick of a previous inline code may be missing
|
LL | /// You could use this function to add 42 to a number `n` (`add(n, 42)`),
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// or even to add a number `n` to 42 (`add(42, b)\`)!
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:83:83
|
LL | /// Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`.
| ^
|
help: a previous inline code might be longer than expected
|
LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// Addition is commutative, which means that `add(a, b) is the same as `add(b, a)\`.
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:87:51
|
LL | /// or even to add a number `n` to 42 (`add(42, n)`)!
| ^
|
help: a previous inline code might be longer than expected
|
LL | /// You could use this function to add 42 to a number `n` (`add(n, 42)`),
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// or even to add a number `n` to 42 (`add(42, n)\`)!
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:91:83
|
LL | /// Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`.
| ^
|
help: the opening backtick of an inline code may be missing
|
LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// Addition is commutative, which means that `add(a, b)` is the same as add(b, a)\`.
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:95:50
|
LL | /// or even to add a number `n` to 42 (add(42, n)`)!
| ^
|
help: the opening backtick of an inline code may be missing
|
LL | /// or even to add a number `n` to 42 (`add(42, n)`)!
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// or even to add a number `n` to 42 (add(42, n)\`)!
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:99:74
|
LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a).
| ^
|
help: the closing backtick of an inline code may be missing
|
LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// Addition is commutative, which means that `add(a, b)` is the same as \`add(b, a).
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:103:51
|
LL | /// or even to add a number `n` to 42 (`add(42, n)`)!
| ^
|
help: a previous inline code might be longer than expected
|
LL | /// You could use this function to add 42 to a number `n` (`add(n, 42)`),
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// or even to add a number `n` to 42 (`add(42, n)\`)!
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:107:1
|
LL | #[doc = "`"]
| ^^^^^^^^^^^^
|
= help: the opening or closing backtick of an inline code may be missing
= help: if you meant to use a literal backtick, escape it
change: `
to this: \`
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:114:1
|
LL | #[doc = concat!("\\", "`")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: the opening backtick of an inline code may be missing
change: \`
to this: `\`
= help: if you meant to use a literal backtick, escape it
change: \`
to this: \\`
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:118:1
|
LL | #[doc = "Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: the opening backtick of a previous inline code may be missing
change: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`.
to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
= help: if you meant to use a literal backtick, escape it
change: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`.
to this: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)\`.
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:122:1
|
LL | #[doc = "Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: a previous inline code might be longer than expected
change: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`.
to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
= help: if you meant to use a literal backtick, escape it
change: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`.
to this: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)\`.
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:126:1
|
LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: the opening backtick of an inline code may be missing
change: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`.
to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
= help: if you meant to use a literal backtick, escape it
change: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`.
to this: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)\`.
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:130:1
|
LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: the closing backtick of an inline code may be missing
change: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a).
to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
= help: if you meant to use a literal backtick, escape it
change: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a).
to this: Addition is commutative, which means that `add(a, b)` is the same as \`add(b, a).
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:135:5
|
LL | /// `foo
| ^
|
help: the closing backtick of an inline code may be missing
|
LL | /// `foo`
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// \`foo
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:139:7
|
LL | /// # `(heading
| ^
|
help: the closing backtick of an inline code may be missing
|
LL | /// # `(heading`
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// # \`(heading
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:141:17
|
LL | /// ## heading2)`
| ^
|
help: the opening backtick of an inline code may be missing
|
LL | /// ## `heading2)`
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// ## heading2)\`
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:144:11
|
LL | /// multi `(
| ^
|
help: the closing backtick of an inline code may be missing
|
LL | /// )` heading
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// multi \`(
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:150:10
|
LL | /// para)`(graph
| ^
|
help: the opening backtick of an inline code may be missing
|
LL | /// `para)`(graph
| +
help: the closing backtick of an inline code may be missing
|
LL | /// para)`(graph`
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// para)\`(graph
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:153:10
|
LL | /// para)`(graph2
| ^
|
help: the opening backtick of an inline code may be missing
|
LL | /// `para)`(graph2
| +
help: the closing backtick of an inline code may be missing
|
LL | /// para)`(graph2`
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// para)\`(graph2
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:156:12
|
LL | /// 1. foo)`
| ^
|
help: the opening backtick of an inline code may be missing
|
LL | /// 1. `foo)`
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// 1. foo)\`
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:158:8
|
LL | /// 2. `(bar
| ^
|
help: the closing backtick of an inline code may be missing
|
LL | /// 2. `(bar`
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// 2. \`(bar
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:160:11
|
LL | /// * baz)`
| ^
|
help: the opening backtick of an inline code may be missing
|
LL | /// * `baz)`
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// * baz)\`
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:162:7
|
LL | /// * `(quux
| ^
|
help: the closing backtick of an inline code may be missing
|
LL | /// * `(quux`
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// * \`(quux
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:165:5
|
LL | /// `#![this_is_actually_an_image(and(not), an = "attribute")]
| ^
|
help: the closing backtick of an inline code may be missing
|
LL | /// `#`![this_is_actually_an_image(and(not), an = "attribute")]
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// \`#![this_is_actually_an_image(and(not), an = "attribute")]
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:168:62
|
LL | /// #![this_is_actually_an_image(and(not), an = "attribute")]`
| ^
|
help: the opening backtick of an inline code may be missing
|
LL | /// `#![this_is_actually_an_image(and(not), an = "attribute")]`
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// #![this_is_actually_an_image(and(not), an = "attribute")]\`
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:173:7
|
LL | /// | `table( | )head` |
| ^
|
help: the closing backtick of an inline code may be missing
|
LL | /// | `table(` | )head` |
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// | \`table( | )head` |
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:173:22
|
LL | /// | `table( | )head` |
| ^
|
help: the opening backtick of an inline code may be missing
|
LL | /// | `table( | `)head` |
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// | `table( | )head\` |
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:177:12
|
LL | /// | table`( | )`body |
| ^
|
help: the opening backtick of an inline code may be missing
|
LL | /// | `table`( | )`body |
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// | table\`( | )`body |
| +
error: unescaped backtick
--> $DIR/unescaped_backticks.rs:177:18
|
LL | /// | table`( | )`body |
| ^
|
help: the opening backtick of an inline code may be missing
|
LL | /// | table`( | `)`body |
| +
help: the closing backtick of an inline code may be missing
|
LL | /// | table`( | )`body` |
| +
help: if you meant to use a literal backtick, escape it
|
LL | /// | table`( | )\`body |
| +
error: aborting due to 63 previous errors