about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustdoc/doctest/make.rs27
-rw-r--r--tests/rustdoc-ui/doctest/auxiliary/macro-after-main.rs1
-rw-r--r--tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs4
-rw-r--r--tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.stdout27
-rw-r--r--tests/rustdoc-ui/doctest/macro-after-main.rs16
-rw-r--r--tests/rustdoc-ui/doctest/macro-after-main.stdout6
-rw-r--r--tests/rustdoc-ui/doctest/test-main-alongside-exprs.rs22
-rw-r--r--tests/rustdoc-ui/doctest/test-main-alongside-exprs.stdout6
8 files changed, 77 insertions, 32 deletions
diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs
index d5c965f7053..4194abc8d57 100644
--- a/src/librustdoc/doctest/make.rs
+++ b/src/librustdoc/doctest/make.rs
@@ -407,17 +407,27 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
                     push_to_s(&mut info.crate_attrs, source, attr.span, &mut prev_span_hi);
                 }
             }
+            let mut has_non_items = false;
             for stmt in &body.stmts {
                 let mut is_extern_crate = false;
                 match stmt.kind {
                     StmtKind::Item(ref item) => {
                         is_extern_crate = check_item(&item, &mut info, crate_name);
                     }
-                    StmtKind::Expr(ref expr) if matches!(expr.kind, ast::ExprKind::Err(_)) => {
-                        reset_error_count(&psess);
-                        return Err(());
+                    StmtKind::Expr(ref expr) => {
+                        if matches!(expr.kind, ast::ExprKind::Err(_)) {
+                            reset_error_count(&psess);
+                            return Err(());
+                        }
+                        has_non_items = true;
                     }
-                    StmtKind::MacCall(ref mac_call) if !info.has_main_fn => {
+                    // We assume that the macro calls will expand to item(s) even though they could
+                    // expand to statements and expressions. And the simple fact that we're trying
+                    // to retrieve a `main` function inside it is a terrible idea.
+                    StmtKind::MacCall(ref mac_call) => {
+                        if info.has_main_fn {
+                            continue;
+                        }
                         let mut iter = mac_call.mac.args.tokens.iter();
 
                         while let Some(token) = iter.next() {
@@ -437,7 +447,9 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
                             }
                         }
                     }
-                    _ => {}
+                    _ => {
+                        has_non_items = true;
+                    }
                 }
 
                 // Weirdly enough, the `Stmt` span doesn't include its attributes, so we need to
@@ -462,6 +474,11 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
                     push_to_s(&mut info.crates, source, span, &mut prev_span_hi);
                 }
             }
+            if has_non_items {
+                // FIXME: if `info.has_main_fn` is `true`, emit a warning here to mention that
+                // this code will not be called.
+                info.has_main_fn = false;
+            }
             Ok(info)
         }
         Err(e) => {
diff --git a/tests/rustdoc-ui/doctest/auxiliary/macro-after-main.rs b/tests/rustdoc-ui/doctest/auxiliary/macro-after-main.rs
new file mode 100644
index 00000000000..ed7584b7425
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/auxiliary/macro-after-main.rs
@@ -0,0 +1 @@
+use std::string::String;
diff --git a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs
index 508faadcf67..ca5dd787467 100644
--- a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs
+++ b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs
@@ -4,12 +4,12 @@
 //@ compile-flags:--test
 //@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
 //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
-//@ failure-status: 101
+//@ check-pass
 
 /// <https://github.com/rust-lang/rust/issues/91014>
 ///
 /// ```rust
-/// struct S {}; // unexpected semicolon after struct def
+/// struct S {};
 ///
 /// fn main() {
 ///    assert_eq!(0, 1);
diff --git a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.stdout b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.stdout
index 9eb8b391e78..1068b98cb0f 100644
--- a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.stdout
+++ b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.stdout
@@ -1,29 +1,6 @@
 
 running 1 test
-test $DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11) ... FAILED
+test $DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11) ... ok
 
-failures:
-
----- $DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11) stdout ----
-error: expected item, found `;`
-  --> $DIR/failed-doctest-extra-semicolon-on-item.rs:12:12
-   |
-LL | struct S {}; // unexpected semicolon after struct def
-   |            ^
-   |
-   = help: braced struct declarations are not followed by a semicolon
-help: remove this semicolon
-   |
-LL - struct S {}; // unexpected semicolon after struct def
-LL + struct S {} // unexpected semicolon after struct def
-   |
-
-error: aborting due to 1 previous error
-
-Couldn't compile the test.
-
-failures:
-    $DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11)
-
-test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
 
diff --git a/tests/rustdoc-ui/doctest/macro-after-main.rs b/tests/rustdoc-ui/doctest/macro-after-main.rs
new file mode 100644
index 00000000000..0a42343f1c2
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/macro-after-main.rs
@@ -0,0 +1,16 @@
+// This test checks a corner case where the macro calls used to be skipped,
+// making them considered as statement, and therefore some cases where
+// `include!` macro was then put into a function body, making the doctest
+// compilation fail.
+
+//@ compile-flags:--test
+//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
+//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
+//@ check-pass
+
+//! ```
+//! include!("./auxiliary/macro-after-main.rs");
+//!
+//! fn main() {}
+//! eprintln!();
+//! ```
diff --git a/tests/rustdoc-ui/doctest/macro-after-main.stdout b/tests/rustdoc-ui/doctest/macro-after-main.stdout
new file mode 100644
index 00000000000..72ffe2b5a27
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/macro-after-main.stdout
@@ -0,0 +1,6 @@
+
+running 1 test
+test $DIR/macro-after-main.rs - (line 11) ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
diff --git a/tests/rustdoc-ui/doctest/test-main-alongside-exprs.rs b/tests/rustdoc-ui/doctest/test-main-alongside-exprs.rs
new file mode 100644
index 00000000000..ee2299c0fd8
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/test-main-alongside-exprs.rs
@@ -0,0 +1,22 @@
+// This test ensures that if there is an expression alongside a `main`
+// function, it will not consider the entire code to be part of the `main`
+// function and will generate its own function to wrap everything.
+//
+// This is a regression test for:
+// * <https://github.com/rust-lang/rust/issues/140162>
+// * <https://github.com/rust-lang/rust/issues/139651>
+//@ compile-flags:--test
+//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
+//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
+//@ check-pass
+
+#![crate_name = "foo"]
+
+//! ```
+//! # if cfg!(miri) { return; }
+//! use std::ops::Deref;
+//!
+//! fn main() {
+//!     println!("Hi!");
+//! }
+//! ```
diff --git a/tests/rustdoc-ui/doctest/test-main-alongside-exprs.stdout b/tests/rustdoc-ui/doctest/test-main-alongside-exprs.stdout
new file mode 100644
index 00000000000..90d7c3546bf
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/test-main-alongside-exprs.stdout
@@ -0,0 +1,6 @@
+
+running 1 test
+test $DIR/test-main-alongside-exprs.rs - (line 15) ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+