]> git.lizzy.rs Git - rust.git/commitdiff
librustdoc: warn on empty doc test
authorTom Milligan <tom@reinfer.io>
Mon, 19 Aug 2019 14:19:26 +0000 (15:19 +0100)
committerTom Milligan <tom@reinfer.io>
Mon, 19 Aug 2019 15:02:57 +0000 (16:02 +0100)
src/librustdoc/passes/check_code_block_syntax.rs
src/test/rustdoc-ui/invalid-syntax.rs
src/test/rustdoc-ui/invalid-syntax.stderr

index 357e17d2d1bc46c4c97cb79576f1cb668efd6ea8..5c4159433c7b2ee387f6260a7541942c97e65905 100644 (file)
@@ -32,27 +32,39 @@ fn check_rust_syntax(&self, item: &clean::Item, dox: &str, code_block: RustCodeB
             dox[code_block.code].to_owned(),
         );
 
-        let has_errors = {
-            let mut has_errors = false;
+        let validation_status = {
+            let mut has_syntax_errors = false;
+            let mut only_whitespace = true;
+            // even if there is a syntax error, we need to run the lexer over the whole file
             let mut lexer = Lexer::new(&sess, source_file, None);
             loop  {
                 match lexer.next_token().kind {
                     token::Eof => break,
-                    token::Unknown(..) => has_errors = true,
-                    _ => (),
+                    token::Whitespace => (),
+                    token::Unknown(..) => has_syntax_errors = true,
+                    _ => only_whitespace = false,
                 }
             }
-            has_errors
+
+            if has_syntax_errors {
+                Some(CodeBlockInvalid::SyntaxError)
+            } else if only_whitespace {
+                Some(CodeBlockInvalid::Empty)
+            } else {
+                None
+            }
         };
 
-        if has_errors {
+        if let Some(code_block_invalid) = validation_status {
             let mut diag = if let Some(sp) =
                 super::source_span_for_markdown_range(self.cx, &dox, &code_block.range, &item.attrs)
             {
-                let mut diag = self
-                    .cx
-                    .sess()
-                    .struct_span_warn(sp, "could not parse code block as Rust code");
+                let warning_message = match code_block_invalid {
+                    CodeBlockInvalid::SyntaxError => "could not parse code block as Rust code",
+                    CodeBlockInvalid::Empty => "Rust code block is empty",
+                };
+
+                let mut diag = self.cx.sess().struct_span_warn(sp, warning_message);
 
                 if code_block.syntax.is_none() && code_block.is_fenced {
                     let sp = sp.from_inner(InnerSpan::new(0, 3));
@@ -96,3 +108,8 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
         self.fold_item_recur(item)
     }
 }
+
+enum CodeBlockInvalid {
+    SyntaxError,
+    Empty,
+}
index 2b02d47d4b851594baf940c05345d6b3b26b2e3c..3ef66e273d0d016d0b6a2b0c1a807c2f7af97087 100644 (file)
@@ -64,3 +64,13 @@ pub fn blargh() {}
 /// \_
 #[doc = "```"]
 pub fn crazy_attrs() {}
+
+/// ```rust
+/// ```
+pub fn empty_rust() {}
+
+/// ```
+///
+///
+/// ```
+pub fn empty_rust_with_whitespace() {}
index 3bebbecb9dfcf5ad196f5a19657d24c8260fb637..36209e29277712b22c660ca333357b41d2f5d05a 100644 (file)
@@ -179,6 +179,28 @@ LL | | #[doc = "```"]
    |
    = help: mark blocks that do not contain Rust code as text: ```text
 
+warning: Rust code block is empty
+  --> $DIR/invalid-syntax.rs:68:5
+   |
+LL |   /// ```rust
+   |  _____^
+LL | | /// ```
+   | |_______^
+
+warning: Rust code block is empty
+  --> $DIR/invalid-syntax.rs:72:5
+   |
+LL |   /// ```
+   |  _____^
+LL | | ///
+LL | | ///
+LL | | /// ```
+   | |_______^
+help: mark blocks that do not contain Rust code as text
+   |
+LL | /// ```text
+   |     ^^^^^^^
+
 error: unknown start of token: \
  --> <rustdoc-highlighting>:1:1
   |