From de16ed35a326041f619de882dfcead1d02623328 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 13 Dec 2024 16:19:34 +0100 Subject: [PATCH 1/4] Correctly handle comments in attributes in doctests source code --- src/librustdoc/doctest/make.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index 3ae60938749ec..f484c98a0d30e 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -520,6 +520,8 @@ fn handle_attr(mod_attr_pending: &mut String, source_info: &mut SourceInfo, edit mod_attr_pending.clear(); } else if mod_attr_pending.ends_with('\\') { mod_attr_pending.push('n'); + } else { + mod_attr_pending.push_str("\n"); } } From 9c4a61ff52a635ef96bd92a2ff1fad4a8bb2ce73 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 13 Dec 2024 16:20:00 +0100 Subject: [PATCH 2/4] Add ui regression test for #134221 --- .../doctest/comment-in-attr-134221.rs | 23 ++++++++++++ .../doctest/comment-in-attr-134221.stdout | 36 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 tests/rustdoc-ui/doctest/comment-in-attr-134221.rs create mode 100644 tests/rustdoc-ui/doctest/comment-in-attr-134221.stdout diff --git a/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs b/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs new file mode 100644 index 0000000000000..fa8cd106659b1 --- /dev/null +++ b/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs @@ -0,0 +1,23 @@ +// Regression test for . +// It checks that even if there are comments in the attributes, the attributes +// will still be generated correctly (and therefore fail in this test). + +//@ compile-flags:--test --test-args --test-threads=1 +//@ failure-status: 101 +//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +/*! +```rust +#![feature( + foo, // +)] +``` + +```rust +#![feature( + foo, +)] +``` +*/ diff --git a/tests/rustdoc-ui/doctest/comment-in-attr-134221.stdout b/tests/rustdoc-ui/doctest/comment-in-attr-134221.stdout new file mode 100644 index 0000000000000..728bfdb010f4f --- /dev/null +++ b/tests/rustdoc-ui/doctest/comment-in-attr-134221.stdout @@ -0,0 +1,36 @@ + +running 2 tests +test $DIR/comment-in-attr-134221.rs - (line 11) ... FAILED +test $DIR/comment-in-attr-134221.rs - (line 17) ... FAILED + +failures: + +---- $DIR/comment-in-attr-134221.rs - (line 11) stdout ---- +error[E0635]: unknown feature `foo` + --> $DIR/comment-in-attr-134221.rs:$LINE:$COL + | +LL | foo, // + | ^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0635`. +Couldn't compile the test. +---- $DIR/comment-in-attr-134221.rs - (line 17) stdout ---- +error[E0635]: unknown feature `foo` + --> $DIR/comment-in-attr-134221.rs:$LINE:$COL + | +LL | foo, + | ^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0635`. +Couldn't compile the test. + +failures: + $DIR/comment-in-attr-134221.rs - (line 11) + $DIR/comment-in-attr-134221.rs - (line 17) + +test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + From 23839853425e8c0c80d0aadb32bf5b4ba1bdf64b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 16 Dec 2024 13:59:41 +0100 Subject: [PATCH 3/4] Also handle cases where attributes are unclosed --- src/librustdoc/doctest/make.rs | 56 +++++++++++++------ .../doctest/comment-in-attr-134221.rs | 4 ++ .../doctest/comment-in-attr-134221.stdout | 18 +++++- 3 files changed, 60 insertions(+), 18 deletions(-) diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index f484c98a0d30e..66549afe5a1e8 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -51,8 +51,17 @@ impl DocTestBuilder { !lang_str.compile_fail && !lang_str.test_harness && !lang_str.standalone_crate }); - let SourceInfo { crate_attrs, maybe_crate_attrs, crates, everything_else } = - partition_source(source, edition); + let Some(SourceInfo { crate_attrs, maybe_crate_attrs, crates, everything_else }) = + partition_source(source, edition) + else { + return Self::invalid( + String::new(), + String::new(), + String::new(), + source.to_string(), + test_id, + ); + }; // Uses librustc_ast to parse the doctest and find if there's a main fn and the extern // crate already is included. @@ -77,18 +86,7 @@ impl DocTestBuilder { else { // If the parser panicked due to a fatal error, pass the test code through unchanged. // The error will be reported during compilation. - return Self { - supports_color: false, - has_main_fn: false, - crate_attrs, - maybe_crate_attrs, - crates, - everything_else, - already_has_extern_crate: false, - test_id, - failed_ast: true, - can_be_merged: false, - }; + return Self::invalid(crate_attrs, maybe_crate_attrs, crates, everything_else, test_id); }; // If the AST returned an error, we don't want this doctest to be merged with the // others. Same if it contains `#[feature]` or `#[no_std]`. @@ -113,6 +111,27 @@ impl DocTestBuilder { } } + fn invalid( + crate_attrs: String, + maybe_crate_attrs: String, + crates: String, + everything_else: String, + test_id: Option, + ) -> Self { + Self { + supports_color: false, + has_main_fn: false, + crate_attrs, + maybe_crate_attrs, + crates, + everything_else, + already_has_extern_crate: false, + test_id, + failed_ast: true, + can_be_merged: false, + } + } + /// Transforms a test into code that can be compiled into a Rust binary, and returns the number of /// lines before the test code begins. pub(crate) fn generate_unique_doctest( @@ -533,7 +552,7 @@ struct SourceInfo { everything_else: String, } -fn partition_source(s: &str, edition: Edition) -> SourceInfo { +fn partition_source(s: &str, edition: Edition) -> Option { #[derive(Copy, Clone, PartialEq)] enum PartitionState { Attrs, @@ -608,11 +627,16 @@ fn partition_source(s: &str, edition: Edition) -> SourceInfo { } } + if !mod_attr_pending.is_empty() { + debug!("invalid doctest code: {s:?}"); + return None; + } + source_info.everything_else = source_info.everything_else.trim().to_string(); debug!("crate_attrs:\n{}{}", source_info.crate_attrs, source_info.maybe_crate_attrs); debug!("crates:\n{}", source_info.crates); debug!("after:\n{}", source_info.everything_else); - source_info + Some(source_info) } diff --git a/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs b/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs index fa8cd106659b1..3689ebe166ad4 100644 --- a/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs +++ b/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs @@ -20,4 +20,8 @@ foo, )] ``` + +```rust +#![ +``` */ diff --git a/tests/rustdoc-ui/doctest/comment-in-attr-134221.stdout b/tests/rustdoc-ui/doctest/comment-in-attr-134221.stdout index 728bfdb010f4f..aa1b27d1f0bd9 100644 --- a/tests/rustdoc-ui/doctest/comment-in-attr-134221.stdout +++ b/tests/rustdoc-ui/doctest/comment-in-attr-134221.stdout @@ -1,7 +1,8 @@ -running 2 tests +running 3 tests test $DIR/comment-in-attr-134221.rs - (line 11) ... FAILED test $DIR/comment-in-attr-134221.rs - (line 17) ... FAILED +test $DIR/comment-in-attr-134221.rs - (line 23) ... FAILED failures: @@ -26,11 +27,24 @@ LL | foo, error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0635`. +Couldn't compile the test. +---- $DIR/comment-in-attr-134221.rs - (line 23) stdout ---- +error: this file contains an unclosed delimiter + --> $DIR/comment-in-attr-134221.rs:$LINE:$COL + | +LL | #![ + | -^ + | | + | unclosed delimiter + +error: aborting due to 1 previous error + Couldn't compile the test. failures: $DIR/comment-in-attr-134221.rs - (line 11) $DIR/comment-in-attr-134221.rs - (line 17) + $DIR/comment-in-attr-134221.rs - (line 23) -test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME +test result: FAILED. 0 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME From c367cc3ef5648d5695fdb795cc66edbff88b4ce9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 16 Dec 2024 17:59:07 +0100 Subject: [PATCH 4/4] Remove unneeded handling of backlines in doctest attributes --- src/librustdoc/doctest/make.rs | 2 -- .../doctest/comment-in-attr-134221-2.rs | 15 +++++++++ .../doctest/comment-in-attr-134221-2.stdout | 31 +++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 tests/rustdoc-ui/doctest/comment-in-attr-134221-2.rs create mode 100644 tests/rustdoc-ui/doctest/comment-in-attr-134221-2.stdout diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index 66549afe5a1e8..a188bc8ebd912 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -537,8 +537,6 @@ fn handle_attr(mod_attr_pending: &mut String, source_info: &mut SourceInfo, edit push_to.push('\n'); // If it's complete, then we can clear the pending content. mod_attr_pending.clear(); - } else if mod_attr_pending.ends_with('\\') { - mod_attr_pending.push('n'); } else { mod_attr_pending.push_str("\n"); } diff --git a/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.rs b/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.rs new file mode 100644 index 0000000000000..8cdd665ff69d2 --- /dev/null +++ b/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.rs @@ -0,0 +1,15 @@ +//@ compile-flags:--test --test-args --test-threads=1 +//@ failure-status: 101 +//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +//! ``` +#![doc = "#![all\ +ow(unused)]"] +//! ``` +//! +//! ``` +#![doc = r#"#![all\ +ow(unused)]"#] +//! ``` diff --git a/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.stdout b/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.stdout new file mode 100644 index 0000000000000..0baff3df14431 --- /dev/null +++ b/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.stdout @@ -0,0 +1,31 @@ + +running 2 tests +test $DIR/comment-in-attr-134221-2.rs - (line 11) ... FAILED +test $DIR/comment-in-attr-134221-2.rs - (line 7) ... ok + +failures: + +---- $DIR/comment-in-attr-134221-2.rs - (line 11) stdout ---- +error: unknown start of token: \ + --> $DIR/comment-in-attr-134221-2.rs:$LINE:$COL + | +LL | #![all\ + | ^ + +error: expected one of `(`, `::`, `=`, `[`, `]`, or `{`, found `ow` + --> $DIR/comment-in-attr-134221-2.rs:$LINE:$COL + | +LL | #![all\ + | - expected one of `(`, `::`, `=`, `[`, `]`, or `{` +LL | ow(unused)] + | ^^ unexpected token + +error: aborting due to 2 previous errors + +Couldn't compile the test. + +failures: + $DIR/comment-in-attr-134221-2.rs - (line 11) + +test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME +