Skip to content

Commit 6a78d59

Browse files
Use old parser if custom_code_classes_in_docs feature is not enabled
1 parent 354397f commit 6a78d59

File tree

1 file changed

+135
-104
lines changed

1 file changed

+135
-104
lines changed

src/librustdoc/html/markdown.rs

+135-104
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,7 @@ impl<'tcx> ExtraInfo<'tcx> {
868868

869869
#[derive(Eq, PartialEq, Clone, Debug)]
870870
pub(crate) struct LangString {
871-
original: String,
871+
pub(crate) original: String,
872872
pub(crate) should_panic: bool,
873873
pub(crate) no_run: bool,
874874
pub(crate) ignore: Ignore,
@@ -1158,6 +1158,29 @@ impl<'a, 'tcx> Iterator for TagIterator<'a, 'tcx> {
11581158
}
11591159
}
11601160

1161+
fn tokens(string: &str) -> impl Iterator<Item = LangStringToken<'_>> {
1162+
// Pandoc, which Rust once used for generating documentation,
1163+
// expects lang strings to be surrounded by `{}` and for each token
1164+
// to be proceeded by a `.`. Since some of these lang strings are still
1165+
// loose in the wild, we strip a pair of surrounding `{}` from the lang
1166+
// string and a leading `.` from each token.
1167+
1168+
let string = string.trim();
1169+
1170+
let first = string.chars().next();
1171+
let last = string.chars().last();
1172+
1173+
let string =
1174+
if first == Some('{') && last == Some('}') { &string[1..string.len() - 1] } else { string };
1175+
1176+
string
1177+
.split(|c| c == ',' || c == ' ' || c == '\t')
1178+
.map(str::trim)
1179+
.map(|token| token.strip_prefix('.').unwrap_or(token))
1180+
.filter(|token| !token.is_empty())
1181+
.map(|token| LangStringToken::LangToken(token))
1182+
}
1183+
11611184
impl Default for LangString {
11621185
fn default() -> Self {
11631186
Self {
@@ -1208,122 +1231,130 @@ impl LangString {
12081231

12091232
data.original = string.to_owned();
12101233

1211-
for token in TagIterator::new(string, extra) {
1212-
match token {
1213-
LangStringToken::LangToken("should_panic") => {
1214-
data.should_panic = true;
1215-
seen_rust_tags = !seen_other_tags;
1216-
}
1217-
LangStringToken::LangToken("no_run") => {
1218-
data.no_run = true;
1219-
seen_rust_tags = !seen_other_tags;
1220-
}
1221-
LangStringToken::LangToken("ignore") => {
1222-
data.ignore = Ignore::All;
1223-
seen_rust_tags = !seen_other_tags;
1224-
}
1225-
LangStringToken::LangToken(x) if x.starts_with("ignore-") => {
1226-
if enable_per_target_ignores {
1227-
ignores.push(x.trim_start_matches("ignore-").to_owned());
1234+
let mut call = |tokens: &mut dyn Iterator<Item = LangStringToken<'_>>| {
1235+
for token in tokens {
1236+
match token {
1237+
LangStringToken::LangToken("should_panic") => {
1238+
data.should_panic = true;
12281239
seen_rust_tags = !seen_other_tags;
12291240
}
1230-
}
1231-
LangStringToken::LangToken("rust") => {
1232-
data.rust = true;
1233-
seen_rust_tags = true;
1234-
}
1235-
LangStringToken::LangToken("custom") => {
1236-
if custom_code_classes_in_docs {
1237-
seen_custom_tag = true;
1238-
} else {
1239-
seen_other_tags = true;
1241+
LangStringToken::LangToken("no_run") => {
1242+
data.no_run = true;
1243+
seen_rust_tags = !seen_other_tags;
12401244
}
1241-
}
1242-
LangStringToken::LangToken("test_harness") => {
1243-
data.test_harness = true;
1244-
seen_rust_tags = !seen_other_tags || seen_rust_tags;
1245-
}
1246-
LangStringToken::LangToken("compile_fail") => {
1247-
data.compile_fail = true;
1248-
seen_rust_tags = !seen_other_tags || seen_rust_tags;
1249-
data.no_run = true;
1250-
}
1251-
LangStringToken::LangToken(x) if x.starts_with("edition") => {
1252-
data.edition = x[7..].parse::<Edition>().ok();
1253-
}
1254-
LangStringToken::LangToken(x)
1255-
if allow_error_code_check && x.starts_with('E') && x.len() == 5 =>
1256-
{
1257-
if x[1..].parse::<u32>().is_ok() {
1258-
data.error_codes.push(x.to_owned());
1245+
LangStringToken::LangToken("ignore") => {
1246+
data.ignore = Ignore::All;
1247+
seen_rust_tags = !seen_other_tags;
1248+
}
1249+
LangStringToken::LangToken(x) if x.starts_with("ignore-") => {
1250+
if enable_per_target_ignores {
1251+
ignores.push(x.trim_start_matches("ignore-").to_owned());
1252+
seen_rust_tags = !seen_other_tags;
1253+
}
1254+
}
1255+
LangStringToken::LangToken("rust") => {
1256+
data.rust = true;
1257+
seen_rust_tags = true;
1258+
}
1259+
LangStringToken::LangToken("custom") => {
1260+
if custom_code_classes_in_docs {
1261+
seen_custom_tag = true;
1262+
} else {
1263+
seen_other_tags = true;
1264+
}
1265+
}
1266+
LangStringToken::LangToken("test_harness") => {
1267+
data.test_harness = true;
12591268
seen_rust_tags = !seen_other_tags || seen_rust_tags;
1260-
} else {
1261-
seen_other_tags = true;
12621269
}
1263-
}
1264-
LangStringToken::LangToken(x) if extra.is_some() => {
1265-
let s = x.to_lowercase();
1266-
if let Some((flag, help)) = if s == "compile-fail"
1267-
|| s == "compile_fail"
1268-
|| s == "compilefail"
1270+
LangStringToken::LangToken("compile_fail") => {
1271+
data.compile_fail = true;
1272+
seen_rust_tags = !seen_other_tags || seen_rust_tags;
1273+
data.no_run = true;
1274+
}
1275+
LangStringToken::LangToken(x) if x.starts_with("edition") => {
1276+
data.edition = x[7..].parse::<Edition>().ok();
1277+
}
1278+
LangStringToken::LangToken(x)
1279+
if allow_error_code_check && x.starts_with('E') && x.len() == 5 =>
12691280
{
1270-
Some((
1271-
"compile_fail",
1272-
"the code block will either not be tested if not marked as a rust one \
1273-
or won't fail if it compiles successfully",
1274-
))
1275-
} else if s == "should-panic" || s == "should_panic" || s == "shouldpanic" {
1276-
Some((
1277-
"should_panic",
1278-
"the code block will either not be tested if not marked as a rust one \
1279-
or won't fail if it doesn't panic when running",
1280-
))
1281-
} else if s == "no-run" || s == "no_run" || s == "norun" {
1282-
Some((
1283-
"no_run",
1284-
"the code block will either not be tested if not marked as a rust one \
1285-
or will be run (which you might not want)",
1286-
))
1287-
} else if s == "test-harness" || s == "test_harness" || s == "testharness" {
1288-
Some((
1289-
"test_harness",
1290-
"the code block will either not be tested if not marked as a rust one \
1291-
or the code will be wrapped inside a main function",
1292-
))
1293-
} else {
1294-
None
1295-
} {
1296-
if let Some(extra) = extra {
1297-
extra.error_invalid_codeblock_attr_with_help(
1298-
format!("unknown attribute `{x}`. Did you mean `{flag}`?"),
1299-
help,
1300-
);
1281+
if x[1..].parse::<u32>().is_ok() {
1282+
data.error_codes.push(x.to_owned());
1283+
seen_rust_tags = !seen_other_tags || seen_rust_tags;
1284+
} else {
1285+
seen_other_tags = true;
13011286
}
13021287
}
1303-
seen_other_tags = true;
1304-
data.unknown.push(x.to_owned());
1305-
}
1306-
LangStringToken::LangToken(x) => {
1307-
seen_other_tags = true;
1308-
data.unknown.push(x.to_owned());
1309-
}
1310-
LangStringToken::KeyValueAttribute(key, value) => {
1311-
if custom_code_classes_in_docs {
1312-
if key == "class" {
1313-
data.added_classes.push(value.to_owned());
1314-
} else if let Some(extra) = extra {
1315-
extra.error_invalid_codeblock_attr(format!(
1316-
"unsupported attribute `{key}`"
1317-
));
1288+
LangStringToken::LangToken(x) if extra.is_some() => {
1289+
let s = x.to_lowercase();
1290+
if let Some((flag, help)) = if s == "compile-fail"
1291+
|| s == "compile_fail"
1292+
|| s == "compilefail"
1293+
{
1294+
Some((
1295+
"compile_fail",
1296+
"the code block will either not be tested if not marked as a rust one \
1297+
or won't fail if it compiles successfully",
1298+
))
1299+
} else if s == "should-panic" || s == "should_panic" || s == "shouldpanic" {
1300+
Some((
1301+
"should_panic",
1302+
"the code block will either not be tested if not marked as a rust one \
1303+
or won't fail if it doesn't panic when running",
1304+
))
1305+
} else if s == "no-run" || s == "no_run" || s == "norun" {
1306+
Some((
1307+
"no_run",
1308+
"the code block will either not be tested if not marked as a rust one \
1309+
or will be run (which you might not want)",
1310+
))
1311+
} else if s == "test-harness" || s == "test_harness" || s == "testharness" {
1312+
Some((
1313+
"test_harness",
1314+
"the code block will either not be tested if not marked as a rust one \
1315+
or the code will be wrapped inside a main function",
1316+
))
1317+
} else {
1318+
None
1319+
} {
1320+
if let Some(extra) = extra {
1321+
extra.error_invalid_codeblock_attr_with_help(
1322+
format!("unknown attribute `{x}`. Did you mean `{flag}`?"),
1323+
help,
1324+
);
1325+
}
13181326
}
1319-
} else {
13201327
seen_other_tags = true;
1328+
data.unknown.push(x.to_owned());
1329+
}
1330+
LangStringToken::LangToken(x) => {
1331+
seen_other_tags = true;
1332+
data.unknown.push(x.to_owned());
1333+
}
1334+
LangStringToken::KeyValueAttribute(key, value) => {
1335+
if custom_code_classes_in_docs {
1336+
if key == "class" {
1337+
data.added_classes.push(value.to_owned());
1338+
} else if let Some(extra) = extra {
1339+
extra.error_invalid_codeblock_attr(format!(
1340+
"unsupported attribute `{key}`"
1341+
));
1342+
}
1343+
} else {
1344+
seen_other_tags = true;
1345+
}
1346+
}
1347+
LangStringToken::ClassAttribute(class) => {
1348+
data.added_classes.push(class.to_owned());
13211349
}
1322-
}
1323-
LangStringToken::ClassAttribute(class) => {
1324-
data.added_classes.push(class.to_owned());
13251350
}
13261351
}
1352+
};
1353+
1354+
if custom_code_classes_in_docs {
1355+
call(&mut TagIterator::new(string, extra).into_iter())
1356+
} else {
1357+
call(&mut tokens(string))
13271358
}
13281359

13291360
// ignore-foo overrides ignore

0 commit comments

Comments
 (0)