Skip to content

Commit 59cc53e

Browse files
committed
Auto merge of #63703 - tommilligan:warn-empty-doctest, r=ollie27
rustdoc: warn on empty doc test Closes #60319. A doc test that only contains whitespace should result in a warning. This PR adds detection of empty doc tests to `check-code-block-syntax`, as having an invalid doc test is mutually exclusive with an empty doc test.
2 parents fba38ac + 0ec2e9f commit 59cc53e

File tree

3 files changed

+59
-10
lines changed

3 files changed

+59
-10
lines changed

src/librustdoc/passes/check_code_block_syntax.rs

+27-10
Original file line numberDiff line numberDiff line change
@@ -32,27 +32,39 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
3232
dox[code_block.code].to_owned(),
3333
);
3434

35-
let has_errors = {
36-
let mut has_errors = false;
35+
let validation_status = {
36+
let mut has_syntax_errors = false;
37+
let mut only_whitespace = true;
38+
// even if there is a syntax error, we need to run the lexer over the whole file
3739
let mut lexer = Lexer::new(&sess, source_file, None);
3840
loop {
3941
match lexer.next_token().kind {
4042
token::Eof => break,
41-
token::Unknown(..) => has_errors = true,
42-
_ => (),
43+
token::Whitespace => (),
44+
token::Unknown(..) => has_syntax_errors = true,
45+
_ => only_whitespace = false,
4346
}
4447
}
45-
has_errors
48+
49+
if has_syntax_errors {
50+
Some(CodeBlockInvalid::SyntaxError)
51+
} else if only_whitespace {
52+
Some(CodeBlockInvalid::Empty)
53+
} else {
54+
None
55+
}
4656
};
4757

48-
if has_errors {
58+
if let Some(code_block_invalid) = validation_status {
4959
let mut diag = if let Some(sp) =
5060
super::source_span_for_markdown_range(self.cx, &dox, &code_block.range, &item.attrs)
5161
{
52-
let mut diag = self
53-
.cx
54-
.sess()
55-
.struct_span_warn(sp, "could not parse code block as Rust code");
62+
let warning_message = match code_block_invalid {
63+
CodeBlockInvalid::SyntaxError => "could not parse code block as Rust code",
64+
CodeBlockInvalid::Empty => "Rust code block is empty",
65+
};
66+
67+
let mut diag = self.cx.sess().struct_span_warn(sp, warning_message);
5668

5769
if code_block.syntax.is_none() && code_block.is_fenced {
5870
let sp = sp.from_inner(InnerSpan::new(0, 3));
@@ -96,3 +108,8 @@ impl<'a, 'tcx> DocFolder for SyntaxChecker<'a, 'tcx> {
96108
self.fold_item_recur(item)
97109
}
98110
}
111+
112+
enum CodeBlockInvalid {
113+
SyntaxError,
114+
Empty,
115+
}

src/test/rustdoc-ui/invalid-syntax.rs

+10
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,13 @@ pub fn blargh() {}
6464
/// \_
6565
#[doc = "```"]
6666
pub fn crazy_attrs() {}
67+
68+
/// ```rust
69+
/// ```
70+
pub fn empty_rust() {}
71+
72+
/// ```
73+
///
74+
///
75+
/// ```
76+
pub fn empty_rust_with_whitespace() {}

src/test/rustdoc-ui/invalid-syntax.stderr

+22
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,28 @@ LL | | #[doc = "```"]
179179
|
180180
= help: mark blocks that do not contain Rust code as text: ```text
181181

182+
warning: Rust code block is empty
183+
--> $DIR/invalid-syntax.rs:68:5
184+
|
185+
LL | /// ```rust
186+
| _____^
187+
LL | | /// ```
188+
| |_______^
189+
190+
warning: Rust code block is empty
191+
--> $DIR/invalid-syntax.rs:72:5
192+
|
193+
LL | /// ```
194+
| _____^
195+
LL | | ///
196+
LL | | ///
197+
LL | | /// ```
198+
| |_______^
199+
help: mark blocks that do not contain Rust code as text
200+
|
201+
LL | /// ```text
202+
| ^^^^^^^
203+
182204
error: unknown start of token: \
183205
--> <rustdoc-highlighting>:1:1
184206
|

0 commit comments

Comments
 (0)