Auto merge of #110994 - matthiaskrgr:rollup-wv4u5yi, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #105848 (rustdoc: Add a new lint for broken inline code) - #110644 (Update tests for libtest `--format json`) - #110950 (Deny the `unsafe_op_in_unsafe_fn` lint in `rustc_arena`.) - #110951 (Add support for LibreSSL 3.7.x) - #110964 (rustdoc: fix weird margins between Deref impl items) - #110979 (windows: kill rust-analyzer-proc-macro-srv before deleting stage0 directory) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
eb62877597
@ -2370,9 +2370,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.84"
|
||||
version = "0.9.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a20eace9dc2d82904039cb76dcf50fb1a0bba071cfd1629720b5d6f1ddba0fa"
|
||||
checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
|
@ -20,6 +20,7 @@
|
||||
#![feature(rustc_attrs)]
|
||||
#![cfg_attr(test, feature(test))]
|
||||
#![feature(strict_provenance)]
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
#![allow(clippy::mut_from_ref)] // Arena allocators are one of the places where this pattern is fine.
|
||||
@ -74,19 +75,27 @@ impl<T> ArenaChunk<T> {
|
||||
#[inline]
|
||||
unsafe fn new(capacity: usize) -> ArenaChunk<T> {
|
||||
ArenaChunk {
|
||||
storage: NonNull::new_unchecked(Box::into_raw(Box::new_uninit_slice(capacity))),
|
||||
storage: NonNull::from(Box::leak(Box::new_uninit_slice(capacity))),
|
||||
entries: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Destroys this arena chunk.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that `len` elements of this chunk have been initialized.
|
||||
#[inline]
|
||||
unsafe fn destroy(&mut self, len: usize) {
|
||||
// The branch on needs_drop() is an -O1 performance optimization.
|
||||
// Without the branch, dropping TypedArena<u8> takes linear time.
|
||||
// Without the branch, dropping TypedArena<T> takes linear time.
|
||||
if mem::needs_drop::<T>() {
|
||||
let slice = self.storage.as_mut();
|
||||
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(&mut slice[..len]));
|
||||
// SAFETY: The caller must ensure that `len` elements of this chunk have
|
||||
// been initialized.
|
||||
unsafe {
|
||||
let slice = self.storage.as_mut();
|
||||
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(&mut slice[..len]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,7 +264,9 @@ impl<T> TypedArena<T> {
|
||||
self.ensure_capacity(len);
|
||||
|
||||
let start_ptr = self.ptr.get();
|
||||
self.ptr.set(start_ptr.add(len));
|
||||
// SAFETY: `self.ensure_capacity` makes sure that there is enough space
|
||||
// for `len` elements.
|
||||
unsafe { self.ptr.set(start_ptr.add(len)) };
|
||||
start_ptr
|
||||
}
|
||||
|
||||
@ -483,6 +494,10 @@ impl DroplessArena {
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that `mem` is valid for writes up to
|
||||
/// `size_of::<T>() * len`.
|
||||
#[inline]
|
||||
unsafe fn write_from_iter<T, I: Iterator<Item = T>>(
|
||||
&self,
|
||||
@ -494,13 +509,18 @@ impl DroplessArena {
|
||||
// Use a manual loop since LLVM manages to optimize it better for
|
||||
// slice iterators
|
||||
loop {
|
||||
let value = iter.next();
|
||||
if i >= len || value.is_none() {
|
||||
// We only return as many items as the iterator gave us, even
|
||||
// though it was supposed to give us `len`
|
||||
return slice::from_raw_parts_mut(mem, i);
|
||||
// SAFETY: The caller must ensure that `mem` is valid for writes up to
|
||||
// `size_of::<T>() * len`.
|
||||
unsafe {
|
||||
match iter.next() {
|
||||
Some(value) if i < len => mem.add(i).write(value),
|
||||
Some(_) | None => {
|
||||
// We only return as many items as the iterator gave us, even
|
||||
// though it was supposed to give us `len`
|
||||
return slice::from_raw_parts_mut(mem, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
ptr::write(mem.add(i), value.unwrap());
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,10 @@ try:
|
||||
except ImportError:
|
||||
lzma = None
|
||||
|
||||
if sys.platform == 'win32':
|
||||
def platform_is_win32():
|
||||
return sys.platform == 'win32'
|
||||
|
||||
if platform_is_win32():
|
||||
EXE_SUFFIX = ".exe"
|
||||
else:
|
||||
EXE_SUFFIX = ""
|
||||
@ -78,7 +81,6 @@ def _download(path, url, probably_big, verbose, exception):
|
||||
if probably_big or verbose:
|
||||
print("downloading {}".format(url))
|
||||
|
||||
platform_is_win32 = sys.platform == 'win32'
|
||||
try:
|
||||
if probably_big or verbose:
|
||||
option = "-#"
|
||||
@ -86,7 +88,7 @@ def _download(path, url, probably_big, verbose, exception):
|
||||
option = "-s"
|
||||
# If curl is not present on Win32, we should not sys.exit
|
||||
# but raise `CalledProcessError` or `OSError` instead
|
||||
require(["curl", "--version"], exception=platform_is_win32)
|
||||
require(["curl", "--version"], exception=platform_is_win32())
|
||||
with open(path, "wb") as outfile:
|
||||
run(["curl", option,
|
||||
"-L", # Follow redirect.
|
||||
@ -99,8 +101,8 @@ def _download(path, url, probably_big, verbose, exception):
|
||||
)
|
||||
except (subprocess.CalledProcessError, OSError, RuntimeError):
|
||||
# see http://serverfault.com/questions/301128/how-to-download
|
||||
if platform_is_win32:
|
||||
run(["PowerShell.exe", "/nologo", "-Command",
|
||||
if platform_is_win32():
|
||||
run_powershell([
|
||||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;",
|
||||
"(New-Object System.Net.WebClient).DownloadFile('{}', '{}')".format(url, path)],
|
||||
verbose=verbose,
|
||||
@ -174,6 +176,10 @@ def run(args, verbose=False, exception=False, is_bootstrap=False, **kwargs):
|
||||
else:
|
||||
sys.exit(err)
|
||||
|
||||
def run_powershell(script, *args, **kwargs):
|
||||
"""Run a powershell script"""
|
||||
run(["PowerShell.exe", "/nologo", "-Command"] + script, *args, **kwargs)
|
||||
|
||||
|
||||
def require(cmd, exit=True, exception=False):
|
||||
'''Run a command, returning its output.
|
||||
@ -229,7 +235,7 @@ def default_build_triple(verbose):
|
||||
print("pre-installed rustc not detected: {}".format(e))
|
||||
print("falling back to auto-detect")
|
||||
|
||||
required = sys.platform != 'win32'
|
||||
required = not platform_is_win32()
|
||||
ostype = require(["uname", "-s"], exit=required)
|
||||
cputype = require(['uname', '-m'], exit=required)
|
||||
|
||||
@ -434,6 +440,23 @@ class RustBuild(object):
|
||||
(not os.path.exists(self.rustc()) or
|
||||
self.program_out_of_date(self.rustc_stamp(), key)):
|
||||
if os.path.exists(bin_root):
|
||||
# HACK: On Windows, we can't delete rust-analyzer-proc-macro-server while it's
|
||||
# running. Kill it.
|
||||
if platform_is_win32():
|
||||
print("Killing rust-analyzer-proc-macro-srv before deleting stage0 toolchain")
|
||||
regex = '{}\\\\(host|{})\\\\stage0\\\\libexec'.format(
|
||||
os.path.basename(self.build_dir),
|
||||
self.build
|
||||
)
|
||||
script = (
|
||||
# NOTE: can't use `taskkill` or `Get-Process -Name` because they error if
|
||||
# the server isn't running.
|
||||
'Get-Process | ' +
|
||||
'Where-Object {$_.Name -eq "rust-analyzer-proc-macro-srv"} |' +
|
||||
'Where-Object {{$_.Path -match "{}"}} |'.format(regex) +
|
||||
'Stop-Process'
|
||||
)
|
||||
run_powershell([script])
|
||||
shutil.rmtree(bin_root)
|
||||
tarball_suffix = '.tar.gz' if lzma is None else '.tar.xz'
|
||||
filename = "rust-std-{}-{}{}".format(
|
||||
|
@ -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
|
||||
```
|
||||
|
@ -1155,10 +1155,10 @@ fn render_assoc_items_inner(
|
||||
let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none());
|
||||
if !non_trait.is_empty() {
|
||||
let mut tmp_buf = Buffer::html();
|
||||
let (render_mode, id) = match what {
|
||||
let (render_mode, id, class_html) = match what {
|
||||
AssocItemRender::All => {
|
||||
write_impl_section_heading(&mut tmp_buf, "Implementations", "implementations");
|
||||
(RenderMode::Normal, "implementations-list".to_owned())
|
||||
(RenderMode::Normal, "implementations-list".to_owned(), "")
|
||||
}
|
||||
AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
|
||||
let id =
|
||||
@ -1175,7 +1175,11 @@ fn render_assoc_items_inner(
|
||||
),
|
||||
&id,
|
||||
);
|
||||
(RenderMode::ForDeref { mut_: deref_mut_ }, cx.derive_id(id))
|
||||
(
|
||||
RenderMode::ForDeref { mut_: deref_mut_ },
|
||||
cx.derive_id(id),
|
||||
r#" class="impl-items""#,
|
||||
)
|
||||
}
|
||||
};
|
||||
let mut impls_buf = Buffer::html();
|
||||
@ -1199,7 +1203,7 @@ fn render_assoc_items_inner(
|
||||
}
|
||||
if !impls_buf.is_empty() {
|
||||
write!(w, "{}", tmp_buf.into_inner()).unwrap();
|
||||
write!(w, "<div id=\"{}\">", id).unwrap();
|
||||
write!(w, "<div id=\"{id}\"{class_html}>").unwrap();
|
||||
write!(w, "{}", impls_buf.into_inner()).unwrap();
|
||||
w.write_str("</div>").unwrap();
|
||||
}
|
||||
@ -1788,12 +1792,14 @@ fn render_impl(
|
||||
.into_string()
|
||||
);
|
||||
}
|
||||
if !default_impl_items.is_empty() || !impl_items.is_empty() {
|
||||
w.write_str("<div class=\"impl-items\">");
|
||||
close_tags.insert_str(0, "</div>");
|
||||
}
|
||||
}
|
||||
if !default_impl_items.is_empty() || !impl_items.is_empty() {
|
||||
w.write_str("<div class=\"impl-items\">");
|
||||
w.push_buffer(default_impl_items);
|
||||
w.push_buffer(impl_items);
|
||||
close_tags.insert_str(0, "</div>");
|
||||
}
|
||||
w.write_str(&close_tags);
|
||||
}
|
||||
|
@ -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)]
|
||||
|
@ -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,
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
416
src/librustdoc/passes/lint/unescaped_backticks.rs
Normal file
416
src/librustdoc/passes/lint/unescaped_backticks.rs
Normal 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 (`) 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}"
|
||||
));
|
||||
}
|
||||
}
|
@ -90,6 +90,9 @@ pub struct TestProps {
|
||||
pub unset_rustc_env: Vec<String>,
|
||||
// Environment settings to use during execution
|
||||
pub exec_env: Vec<(String, String)>,
|
||||
// Environment variables to unset prior to execution.
|
||||
// Variables are unset before applying 'exec_env'
|
||||
pub unset_exec_env: Vec<String>,
|
||||
// Build documentation for all specified aux-builds as well
|
||||
pub build_aux_docs: bool,
|
||||
// Flag to force a crate to be built with the host architecture
|
||||
@ -198,6 +201,7 @@ mod directives {
|
||||
pub const AUX_CRATE: &'static str = "aux-crate";
|
||||
pub const EXEC_ENV: &'static str = "exec-env";
|
||||
pub const RUSTC_ENV: &'static str = "rustc-env";
|
||||
pub const UNSET_EXEC_ENV: &'static str = "unset-exec-env";
|
||||
pub const UNSET_RUSTC_ENV: &'static str = "unset-rustc-env";
|
||||
pub const FORBID_OUTPUT: &'static str = "forbid-output";
|
||||
pub const CHECK_TEST_LINE_NUMBERS_MATCH: &'static str = "check-test-line-numbers-match";
|
||||
@ -231,6 +235,7 @@ impl TestProps {
|
||||
rustc_env: vec![],
|
||||
unset_rustc_env: vec![],
|
||||
exec_env: vec![],
|
||||
unset_exec_env: vec![],
|
||||
build_aux_docs: false,
|
||||
force_host: false,
|
||||
check_stdout: false,
|
||||
@ -382,6 +387,12 @@ impl TestProps {
|
||||
&mut self.exec_env,
|
||||
Config::parse_env,
|
||||
);
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
UNSET_EXEC_ENV,
|
||||
&mut self.unset_exec_env,
|
||||
|r| r,
|
||||
);
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
RUSTC_ENV,
|
||||
|
@ -165,11 +165,15 @@ pub(super) fn parse_cfg_name_directive<'a>(
|
||||
message: "when the architecture is part of the Thumb family"
|
||||
}
|
||||
|
||||
// Technically the locally built compiler uses the "dev" channel rather than the "nightly"
|
||||
// channel, even though most people don't know or won't care about it. To avoid confusion, we
|
||||
// treat the "dev" channel as the "nightly" channel when processing the directive.
|
||||
condition! {
|
||||
name: &config.channel,
|
||||
name: if config.channel == "dev" { "nightly" } else { &config.channel },
|
||||
allowed_names: &["stable", "beta", "nightly"],
|
||||
message: "when the release channel is {name}",
|
||||
}
|
||||
|
||||
condition! {
|
||||
name: "cross-compile",
|
||||
condition: config.target != config.host,
|
||||
|
@ -1614,8 +1614,13 @@ impl<'test> TestCx<'test> {
|
||||
test_client
|
||||
.args(&["run", &support_libs.len().to_string(), &prog])
|
||||
.args(support_libs)
|
||||
.args(args)
|
||||
.envs(env.clone());
|
||||
.args(args);
|
||||
|
||||
for key in &self.props.unset_exec_env {
|
||||
test_client.env_remove(key);
|
||||
}
|
||||
test_client.envs(env.clone());
|
||||
|
||||
self.compose_and_run(
|
||||
test_client,
|
||||
self.config.run_lib_path.to_str().unwrap(),
|
||||
@ -1627,7 +1632,13 @@ impl<'test> TestCx<'test> {
|
||||
let aux_dir = self.aux_output_dir_name();
|
||||
let ProcArgs { prog, args } = self.make_run_args();
|
||||
let mut wr_run = Command::new("wr-run");
|
||||
wr_run.args(&[&prog]).args(args).envs(env.clone());
|
||||
wr_run.args(&[&prog]).args(args);
|
||||
|
||||
for key in &self.props.unset_exec_env {
|
||||
wr_run.env_remove(key);
|
||||
}
|
||||
wr_run.envs(env.clone());
|
||||
|
||||
self.compose_and_run(
|
||||
wr_run,
|
||||
self.config.run_lib_path.to_str().unwrap(),
|
||||
@ -1639,7 +1650,13 @@ impl<'test> TestCx<'test> {
|
||||
let aux_dir = self.aux_output_dir_name();
|
||||
let ProcArgs { prog, args } = self.make_run_args();
|
||||
let mut program = Command::new(&prog);
|
||||
program.args(args).current_dir(&self.output_base_dir()).envs(env.clone());
|
||||
program.args(args).current_dir(&self.output_base_dir());
|
||||
|
||||
for key in &self.props.unset_exec_env {
|
||||
program.env_remove(key);
|
||||
}
|
||||
program.envs(env.clone());
|
||||
|
||||
self.compose_and_run(
|
||||
program,
|
||||
self.config.run_lib_path.to_str().unwrap(),
|
||||
|
342
tests/rustdoc-ui/unescaped_backticks.rs
Normal file
342
tests/rustdoc-ui/unescaped_backticks.rs
Normal 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() {}
|
||||
|
||||
/// `
|
||||
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 {}
|
||||
}
|
959
tests/rustdoc-ui/unescaped_backticks.stderr
Normal file
959
tests/rustdoc-ui/unescaped_backticks.stderr
Normal 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
|
||||
|
43
tests/rustdoc/deref/deref-multiple-impl-blocks.rs
Normal file
43
tests/rustdoc/deref/deref-multiple-impl-blocks.rs
Normal file
@ -0,0 +1,43 @@
|
||||
#![crate_name="foo"]
|
||||
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
// @has foo/struct.Vec.html
|
||||
// @count - '//h2[@id="deref-methods-Slice"]' 1
|
||||
// @count - '//div[@id="deref-methods-Slice-1"]' 1
|
||||
// @count - '//div[@id="deref-methods-Slice-1"][@class="impl-items"]' 1
|
||||
// @count - '//div[@id="deref-methods-Slice-1"]/div[@class="impl-items"]' 0
|
||||
pub struct Vec;
|
||||
|
||||
pub struct Slice;
|
||||
|
||||
impl Deref for Vec {
|
||||
type Target = Slice;
|
||||
fn deref(&self) -> &Slice {
|
||||
&Slice
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Vec {
|
||||
fn deref_mut(&mut self) -> &mut Slice {
|
||||
&mut Slice
|
||||
}
|
||||
}
|
||||
|
||||
impl Slice {
|
||||
pub fn sort_floats(&mut self) {
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
|
||||
impl Slice {
|
||||
pub fn sort(&mut self) {
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
|
||||
impl Slice {
|
||||
pub fn len(&self) {
|
||||
todo!();
|
||||
}
|
||||
}
|
18
tests/ui/feature-gates/test-listing-format-json.rs
Normal file
18
tests/ui/feature-gates/test-listing-format-json.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// no-prefer-dynamic
|
||||
// compile-flags: --test
|
||||
// run-flags: --list --format json -Zunstable-options
|
||||
// run-fail
|
||||
// check-run-results
|
||||
// ignore-nightly
|
||||
// unset-exec-env:RUSTC_BOOTSTRAP
|
||||
|
||||
#![cfg(test)]
|
||||
#[test]
|
||||
fn m_test() {}
|
||||
|
||||
#[test]
|
||||
#[ignore = "not yet implemented"]
|
||||
fn z_test() {}
|
||||
|
||||
#[test]
|
||||
fn a_test() {}
|
@ -0,0 +1 @@
|
||||
error: the option `Z` is only accepted on the nightly compiler
|
@ -3,6 +3,7 @@
|
||||
// run-flags: --list --format json -Zunstable-options
|
||||
// run-pass
|
||||
// check-run-results
|
||||
// only-nightly
|
||||
// normalize-stdout-test: "fake-test-src-base/test-attrs/" -> "$$DIR/"
|
||||
// normalize-stdout-test: "fake-test-src-base\\test-attrs\\" -> "$$DIR/"
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
{ "type": "suite", "event": "discovery" }
|
||||
{ "type": "test", "event": "discovered", "name": "a_test", "ignore": false, "ignore_message": "", "source_path": "$DIR/tests-listing-format-json.rs", "start_line": 20, "start_col": 4, "end_line": 20, "end_col": 10 }
|
||||
{ "type": "test", "event": "discovered", "name": "m_test", "ignore": false, "ignore_message": "", "source_path": "$DIR/tests-listing-format-json.rs", "start_line": 13, "start_col": 4, "end_line": 13, "end_col": 10 }
|
||||
{ "type": "test", "event": "discovered", "name": "z_test", "ignore": true, "ignore_message": "not yet implemented", "source_path": "$DIR/tests-listing-format-json.rs", "start_line": 17, "start_col": 4, "end_line": 17, "end_col": 10 }
|
||||
{ "type": "test", "event": "discovered", "name": "a_test", "ignore": false, "ignore_message": "", "source_path": "$DIR/tests-listing-format-json.rs", "start_line": 21, "start_col": 4, "end_line": 21, "end_col": 10 }
|
||||
{ "type": "test", "event": "discovered", "name": "m_test", "ignore": false, "ignore_message": "", "source_path": "$DIR/tests-listing-format-json.rs", "start_line": 14, "start_col": 4, "end_line": 14, "end_col": 10 }
|
||||
{ "type": "test", "event": "discovered", "name": "z_test", "ignore": true, "ignore_message": "not yet implemented", "source_path": "$DIR/tests-listing-format-json.rs", "start_line": 18, "start_col": 4, "end_line": 18, "end_col": 10 }
|
||||
{ "type": "suite", "event": "completed", "tests": 3, "benchmarks": 0, "total": 3, "ignored": 1 }
|
||||
|
Loading…
x
Reference in New Issue
Block a user