diff options
Diffstat (limited to 'src/librustdoc/doctest/make.rs')
| -rw-r--r-- | src/librustdoc/doctest/make.rs | 60 |
1 files changed, 42 insertions, 18 deletions
diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index 3ae60938749..a188bc8ebd9 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<String>, + ) -> 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( @@ -518,8 +537,8 @@ 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"); } } @@ -531,7 +550,7 @@ struct SourceInfo { everything_else: String, } -fn partition_source(s: &str, edition: Edition) -> SourceInfo { +fn partition_source(s: &str, edition: Edition) -> Option<SourceInfo> { #[derive(Copy, Clone, PartialEq)] enum PartitionState { Attrs, @@ -606,11 +625,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) } |
