@@ -868,7 +868,7 @@ impl<'tcx> ExtraInfo<'tcx> {
868
868
869
869
#[ derive( Eq , PartialEq , Clone , Debug ) ]
870
870
pub ( crate ) struct LangString {
871
- original : String ,
871
+ pub ( crate ) original : String ,
872
872
pub ( crate ) should_panic : bool ,
873
873
pub ( crate ) no_run : bool ,
874
874
pub ( crate ) ignore : Ignore ,
@@ -1158,6 +1158,29 @@ impl<'a, 'tcx> Iterator for TagIterator<'a, 'tcx> {
1158
1158
}
1159
1159
}
1160
1160
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
+
1161
1184
impl Default for LangString {
1162
1185
fn default ( ) -> Self {
1163
1186
Self {
@@ -1208,122 +1231,130 @@ impl LangString {
1208
1231
1209
1232
data. original = string. to_owned ( ) ;
1210
1233
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 ;
1228
1239
seen_rust_tags = !seen_other_tags;
1229
1240
}
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;
1240
1244
}
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 ;
1259
1268
seen_rust_tags = !seen_other_tags || seen_rust_tags;
1260
- } else {
1261
- seen_other_tags = true ;
1262
1269
}
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 =>
1269
1280
{
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 ;
1301
1286
}
1302
1287
}
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
+ }
1318
1326
}
1319
- } else {
1320
1327
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 ( ) ) ;
1321
1349
}
1322
- }
1323
- LangStringToken :: ClassAttribute ( class) => {
1324
- data. added_classes . push ( class. to_owned ( ) ) ;
1325
1350
}
1326
1351
}
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) )
1327
1358
}
1328
1359
1329
1360
// ignore-foo overrides ignore
0 commit comments