Skip to content

Commit cfb20bc

Browse files
notriddlecuviper
authored andcommitted
rustdoc: do not run doctests with invalid langstrings
(cherry picked from commit 7c4150f)
1 parent 1953a13 commit cfb20bc

File tree

3 files changed

+30
-7
lines changed

3 files changed

+30
-7
lines changed

src/librustdoc/html/markdown.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -925,6 +925,7 @@ pub(crate) struct TagIterator<'a, 'tcx> {
925925
data: &'a str,
926926
is_in_attribute_block: bool,
927927
extra: Option<&'a ExtraInfo<'tcx>>,
928+
is_error: bool,
928929
}
929930

930931
#[derive(Clone, Debug, Eq, PartialEq)]
@@ -951,13 +952,20 @@ struct Indices {
951952

952953
impl<'a, 'tcx> TagIterator<'a, 'tcx> {
953954
pub(crate) fn new(data: &'a str, extra: Option<&'a ExtraInfo<'tcx>>) -> Self {
954-
Self { inner: data.char_indices().peekable(), data, is_in_attribute_block: false, extra }
955+
Self {
956+
inner: data.char_indices().peekable(),
957+
data,
958+
is_in_attribute_block: false,
959+
extra,
960+
is_error: false,
961+
}
955962
}
956963

957-
fn emit_error(&self, err: impl Into<DiagMessage>) {
964+
fn emit_error(&mut self, err: impl Into<DiagMessage>) {
958965
if let Some(extra) = self.extra {
959966
extra.error_invalid_codeblock_attr(err);
960967
}
968+
self.is_error = true;
961969
}
962970

963971
fn skip_separators(&mut self) -> Option<usize> {
@@ -1155,6 +1163,9 @@ impl<'a, 'tcx> Iterator for TagIterator<'a, 'tcx> {
11551163
type Item = LangStringToken<'a>;
11561164

11571165
fn next(&mut self) -> Option<Self::Item> {
1166+
if self.is_error {
1167+
return None;
1168+
}
11581169
let Some(start) = self.skip_separators() else {
11591170
if self.is_in_attribute_block {
11601171
self.emit_error("unclosed attribute block (`{}`): missing `}` at the end");
@@ -1343,14 +1354,15 @@ impl LangString {
13431354
}
13441355
};
13451356

1346-
call(&mut TagIterator::new(string, extra));
1357+
let mut tag_iter = TagIterator::new(string, extra);
1358+
call(&mut tag_iter);
13471359

13481360
// ignore-foo overrides ignore
13491361
if !ignores.is_empty() {
13501362
data.ignore = Ignore::Some(ignores);
13511363
}
13521364

1353-
data.rust &= !seen_custom_tag && (!seen_other_tags || seen_rust_tags);
1365+
data.rust &= !seen_custom_tag && (!seen_other_tags || seen_rust_tags) && !tag_iter.is_error;
13541366

13551367
data
13561368
}

src/librustdoc/html/markdown/tests.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ fn test_lang_string_parse() {
6161
..Default::default()
6262
});
6363
// error
64-
t(LangString { original: "{rust}".into(), rust: true, ..Default::default() });
64+
t(LangString { original: "{rust}".into(), rust: false, ..Default::default() });
6565
t(LangString {
6666
original: "{.rust}".into(),
6767
rust: true,
@@ -233,7 +233,7 @@ fn test_lang_string_parse() {
233233
..Default::default()
234234
});
235235
// error
236-
t(LangString { original: "{class=first=second}".into(), rust: true, ..Default::default() });
236+
t(LangString { original: "{class=first=second}".into(), rust: false, ..Default::default() });
237237
// error
238238
t(LangString {
239239
original: "{class=first.second}".into(),
@@ -261,7 +261,7 @@ fn test_lang_string_parse() {
261261
..Default::default()
262262
});
263263
// error
264-
t(LangString { original: r#"{class=f"irst"}"#.into(), rust: true, ..Default::default() });
264+
t(LangString { original: r#"{class=f"irst"}"#.into(), rust: false, ..Default::default() });
265265
}
266266

267267
#[test]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//@ compile-flags:--test
2+
#![allow(rustdoc::invalid_codeblock_attributes)]
3+
4+
// https://github.com/rust-lang/rust/pull/124577#issuecomment-2276034737
5+
6+
// Test that invalid langstrings don't get run.
7+
8+
/// ```{rust,ignore}
9+
/// panic!();
10+
/// ```
11+
pub struct Foo;

0 commit comments

Comments
 (0)