diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index a7f0df5afa98f..e9fc3a3ffcee8 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -925,6 +925,7 @@ pub(crate) struct TagIterator<'a, 'tcx> {
data: &'a str,
is_in_attribute_block: bool,
extra: Option<&'a ExtraInfo<'tcx>>,
+ is_error: bool,
}
#[derive(Clone, Debug, Eq, PartialEq)]
@@ -951,13 +952,20 @@ struct Indices {
impl<'a, 'tcx> TagIterator<'a, 'tcx> {
pub(crate) fn new(data: &'a str, extra: Option<&'a ExtraInfo<'tcx>>) -> Self {
- Self { inner: data.char_indices().peekable(), data, is_in_attribute_block: false, extra }
+ Self {
+ inner: data.char_indices().peekable(),
+ data,
+ is_in_attribute_block: false,
+ extra,
+ is_error: false,
+ }
}
- fn emit_error(&self, err: impl Into) {
+ fn emit_error(&mut self, err: impl Into) {
if let Some(extra) = self.extra {
extra.error_invalid_codeblock_attr(err);
}
+ self.is_error = true;
}
fn skip_separators(&mut self) -> Option {
@@ -1155,6 +1163,9 @@ impl<'a, 'tcx> Iterator for TagIterator<'a, 'tcx> {
type Item = LangStringToken<'a>;
fn next(&mut self) -> Option {
+ if self.is_error {
+ return None;
+ }
let Some(start) = self.skip_separators() else {
if self.is_in_attribute_block {
self.emit_error("unclosed attribute block (`{}`): missing `}` at the end");
@@ -1343,14 +1354,15 @@ impl LangString {
}
};
- call(&mut TagIterator::new(string, extra));
+ let mut tag_iter = TagIterator::new(string, extra);
+ call(&mut tag_iter);
// ignore-foo overrides ignore
if !ignores.is_empty() {
data.ignore = Ignore::Some(ignores);
}
- data.rust &= !seen_custom_tag && (!seen_other_tags || seen_rust_tags);
+ data.rust &= !seen_custom_tag && (!seen_other_tags || seen_rust_tags) && !tag_iter.is_error;
data
}
diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs
index fb74c079c9a4e..23da2f0cc7fb4 100644
--- a/src/librustdoc/html/markdown/tests.rs
+++ b/src/librustdoc/html/markdown/tests.rs
@@ -61,7 +61,7 @@ fn test_lang_string_parse() {
..Default::default()
});
// error
- t(LangString { original: "{rust}".into(), rust: true, ..Default::default() });
+ t(LangString { original: "{rust}".into(), rust: false, ..Default::default() });
t(LangString {
original: "{.rust}".into(),
rust: true,
@@ -233,7 +233,7 @@ fn test_lang_string_parse() {
..Default::default()
});
// error
- t(LangString { original: "{class=first=second}".into(), rust: true, ..Default::default() });
+ t(LangString { original: "{class=first=second}".into(), rust: false, ..Default::default() });
// error
t(LangString {
original: "{class=first.second}".into(),
@@ -261,7 +261,7 @@ fn test_lang_string_parse() {
..Default::default()
});
// error
- t(LangString { original: r#"{class=f"irst"}"#.into(), rust: true, ..Default::default() });
+ t(LangString { original: r#"{class=f"irst"}"#.into(), rust: false, ..Default::default() });
}
#[test]
diff --git a/tests/rustdoc/doctest/doctest-no-run-invalid-langstring-124577.rs b/tests/rustdoc/doctest/doctest-no-run-invalid-langstring-124577.rs
new file mode 100644
index 0000000000000..b3e993e8ee939
--- /dev/null
+++ b/tests/rustdoc/doctest/doctest-no-run-invalid-langstring-124577.rs
@@ -0,0 +1,11 @@
+//@ compile-flags:--test
+#![allow(rustdoc::invalid_codeblock_attributes)]
+
+// https://github.com/rust-lang/rust/pull/124577#issuecomment-2276034737
+
+// Test that invalid langstrings don't get run.
+
+/// ```{rust,ignore}
+/// panic!();
+/// ```
+pub struct Foo;