Skip to content

Commit b69da28

Browse files
Jarchooli-obk
authored andcommitted
Allow global prefix when matching diagnostic codes.
1 parent d727690 commit b69da28

File tree

4 files changed

+100
-9
lines changed

4 files changed

+100
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
* Started maintaining a changelog
1313
* `Config::comment_defaults` allows setting `//@` comments for all tests
1414
* `//~` comments can now specify just an error code or lint name, without any message. ERROR level is implied
15+
* `Revisioned::diagnostic_code_prefix` allows stripping a prefix of diagnostic codes to avoid having to repeat `clippy::` in all messages
1516

1617
### Fixed
1718

src/lib.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,7 @@ fn run_rustfix(
915915
edition,
916916
mode: OptWithLine::new(Mode::Pass, Span::default()),
917917
no_rustfix: OptWithLine::new((), Span::default()),
918+
diagnostic_code_prefix: OptWithLine::new(String::new(), Span::default()),
918919
needs_asm_support: false,
919920
},
920921
))
@@ -1071,12 +1072,19 @@ fn check_annotations(
10711072
});
10721073
}
10731074
}
1075+
let diagnostic_code_prefix = comments
1076+
.find_one_for_revision(revision, "diagnostic_code_prefix", |r| {
1077+
r.diagnostic_code_prefix.clone()
1078+
})?
1079+
.into_inner()
1080+
.map(|s| s.content)
1081+
.unwrap_or_default();
10741082

10751083
// The order on `Level` is such that `Error` is the highest level.
10761084
// We will ensure that *all* diagnostics of level at least `lowest_annotation_level`
10771085
// are matched.
10781086
let mut lowest_annotation_level = Level::Error;
1079-
for &ErrorMatch { ref kind, line } in comments
1087+
'err: for &ErrorMatch { ref kind, line } in comments
10801088
.for_revision(revision)
10811089
.flat_map(|r| r.error_matches.iter())
10821090
{
@@ -1107,13 +1115,18 @@ fn check_annotations(
11071115
}
11081116
}
11091117
ErrorMatchKind::Code(code) => {
1110-
let found = msgs.iter().position(|msg| {
1111-
msg.level == Level::Error
1112-
&& msg.code.as_ref().is_some_and(|msg| *msg == **code)
1113-
});
1114-
if let Some(found) = found {
1115-
msgs.remove(found);
1116-
continue;
1118+
for (i, msg) in msgs.iter().enumerate() {
1119+
if msg.level != Level::Error {
1120+
continue;
1121+
}
1122+
let Some(msg_code) = &msg.code else { continue };
1123+
let Some(msg) = msg_code.strip_prefix(&diagnostic_code_prefix) else {
1124+
continue;
1125+
};
1126+
if msg == **code {
1127+
msgs.remove(i);
1128+
continue 'err;
1129+
}
11171130
}
11181131
}
11191132
}
@@ -1125,7 +1138,7 @@ fn check_annotations(
11251138
expected_line: Some(line),
11261139
},
11271140
ErrorMatchKind::Code(code) => Error::CodeNotFound {
1128-
code: code.clone(),
1141+
code: Spanned::new(format!("{}{}", diagnostic_code_prefix, **code), code.span()),
11291142
expected_line: Some(line),
11301143
},
11311144
});

src/parser.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ pub struct Revisioned {
164164
pub(crate) needs_asm_support: bool,
165165
/// Don't run [`rustfix`] for this test
166166
pub no_rustfix: OptWithLine<()>,
167+
/// Prefix added to all diagnostic code matchers. Note this will make it impossible
168+
/// match codes which do not contain this prefix.
169+
pub diagnostic_code_prefix: OptWithLine<String>,
167170
}
168171

169172
#[derive(Debug)]
@@ -330,6 +333,7 @@ impl Comments {
330333
mode,
331334
needs_asm_support,
332335
no_rustfix,
336+
diagnostic_code_prefix,
333337
} = parser.comments.base();
334338
if span.is_dummy() {
335339
*span = defaults.span;
@@ -356,6 +360,9 @@ impl Comments {
356360
if no_rustfix.is_none() {
357361
*no_rustfix = defaults.no_rustfix;
358362
}
363+
if diagnostic_code_prefix.is_none() {
364+
*diagnostic_code_prefix = defaults.diagnostic_code_prefix;
365+
}
359366
*needs_asm_support |= defaults.needs_asm_support;
360367

361368
if parser.errors.is_empty() {

src/tests.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,3 +451,73 @@ fn main() {
451451
}
452452
}
453453
}
454+
455+
#[test]
456+
fn find_code_with_prefix() {
457+
let s = r"
458+
fn main() {
459+
let _x: i32 = 0u32; //~ E0308
460+
}
461+
";
462+
let mut config = config();
463+
config.comment_defaults.base().diagnostic_code_prefix =
464+
Spanned::dummy("prefix::".to_string()).into();
465+
let comments = Comments::parse(s, config.comment_defaults.clone(), Path::new("")).unwrap();
466+
{
467+
let messages = vec![
468+
vec![],
469+
vec![],
470+
vec![],
471+
vec![Message {
472+
message: "mismatched types".to_string(),
473+
level: Level::Error,
474+
line_col: None,
475+
code: Some("prefix::E0308".into()),
476+
}],
477+
];
478+
let mut errors = vec![];
479+
check_annotations(
480+
messages,
481+
vec![],
482+
Path::new("moobar"),
483+
&mut errors,
484+
"",
485+
&comments,
486+
)
487+
.unwrap();
488+
match &errors[..] {
489+
[] => {}
490+
_ => panic!("{:#?}", errors),
491+
}
492+
}
493+
494+
// missing prefix
495+
{
496+
let messages = vec![
497+
vec![],
498+
vec![],
499+
vec![],
500+
vec![Message {
501+
message: "mismatched types".to_string(),
502+
level: Level::Error,
503+
line_col: None,
504+
code: Some("E0308".into()),
505+
}],
506+
];
507+
let mut errors = vec![];
508+
check_annotations(
509+
messages,
510+
vec![],
511+
Path::new("moobar"),
512+
&mut errors,
513+
"",
514+
&comments,
515+
)
516+
.unwrap();
517+
match &errors[..] {
518+
[Error::CodeNotFound { code, .. }, Error::ErrorsWithoutPattern { msgs, .. }]
519+
if **code == "prefix::E0308" && code.line().get() == 3 && msgs.len() == 1 => {}
520+
_ => panic!("{:#?}", errors),
521+
}
522+
}
523+
}

0 commit comments

Comments
 (0)