Skip to content

Commit

Permalink
Allow global prefix when matching diagnostic codes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarcho authored and oli-obk committed Nov 8, 2023
1 parent d727690 commit 091439d
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 9 deletions.
31 changes: 22 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,7 @@ fn run_rustfix(
edition,
mode: OptWithLine::new(Mode::Pass, Span::default()),
no_rustfix: OptWithLine::new((), Span::default()),
diagnostic_code_prefix: OptWithLine::new(String::new(), Span::default()),
needs_asm_support: false,
},
))
Expand Down Expand Up @@ -1071,12 +1072,19 @@ fn check_annotations(
});
}
}
let diagnostic_code_prefix = comments
.find_one_for_revision(revision, "diagnostic_code_prefix", |r| {
r.diagnostic_code_prefix.clone()
})?
.into_inner()
.map(|s| s.content)
.unwrap_or_default();

// The order on `Level` is such that `Error` is the highest level.
// We will ensure that *all* diagnostics of level at least `lowest_annotation_level`
// are matched.
let mut lowest_annotation_level = Level::Error;
for &ErrorMatch { ref kind, line } in comments
'err: for &ErrorMatch { ref kind, line } in comments
.for_revision(revision)
.flat_map(|r| r.error_matches.iter())
{
Expand Down Expand Up @@ -1107,13 +1115,18 @@ fn check_annotations(
}
}
ErrorMatchKind::Code(code) => {
let found = msgs.iter().position(|msg| {
msg.level == Level::Error
&& msg.code.as_ref().is_some_and(|msg| *msg == **code)
});
if let Some(found) = found {
msgs.remove(found);
continue;
for (i, msg) in msgs.iter().enumerate() {
if msg.level != Level::Error {
continue;
}
let Some(msg_code) = &msg.code else { continue };
let Some(msg) = msg_code.strip_prefix(&diagnostic_code_prefix) else {
continue;
};
if msg == **code {
msgs.remove(i);
continue 'err;
}
}
}
}
Expand All @@ -1125,7 +1138,7 @@ fn check_annotations(
expected_line: Some(line),
},
ErrorMatchKind::Code(code) => Error::CodeNotFound {
code: code.clone(),
code: Spanned::new(format!("{}{}", diagnostic_code_prefix, **code), code.span()),
expected_line: Some(line),
},
});
Expand Down
7 changes: 7 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ pub struct Revisioned {
pub(crate) needs_asm_support: bool,
/// Don't run [`rustfix`] for this test
pub no_rustfix: OptWithLine<()>,
/// Prefix added to all diagnostic code matchers. Note this will make it impossible
/// match codes which do not contain this prefix.
pub diagnostic_code_prefix: OptWithLine<String>,
}

#[derive(Debug)]
Expand Down Expand Up @@ -330,6 +333,7 @@ impl Comments {
mode,
needs_asm_support,
no_rustfix,
diagnostic_code_prefix,
} = parser.comments.base();
if span.is_dummy() {
*span = defaults.span;
Expand All @@ -356,6 +360,9 @@ impl Comments {
if no_rustfix.is_none() {
*no_rustfix = defaults.no_rustfix;
}
if diagnostic_code_prefix.is_none() {
*diagnostic_code_prefix = defaults.diagnostic_code_prefix;
}
*needs_asm_support |= defaults.needs_asm_support;

if parser.errors.is_empty() {
Expand Down
70 changes: 70 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,3 +451,73 @@ fn main() {
}
}
}

#[test]
fn find_code_with_prefix() {
let s = r"
fn main() {
let _x: i32 = 0u32; //~ E0308
}
";
let mut config = config();
config.comment_defaults.base().diagnostic_code_prefix =
Spanned::dummy("prefix::".to_string()).into();
let comments = Comments::parse(s, config.comment_defaults.clone(), Path::new("")).unwrap();
{
let messages = vec![
vec![],
vec![],
vec![],
vec![Message {
message: "mismatched types".to_string(),
level: Level::Error,
line_col: None,
code: Some("prefix::E0308".into()),
}],
];
let mut errors = vec![];
check_annotations(
messages,
vec![],
Path::new("moobar"),
&mut errors,
"",
&comments,
)
.unwrap();
match &errors[..] {
[] => {}
_ => panic!("{:#?}", errors),
}
}

// missing prefix
{
let messages = vec![
vec![],
vec![],
vec![],
vec![Message {
message: "mismatched types".to_string(),
level: Level::Error,
line_col: None,
code: Some("E0308".into()),
}],
];
let mut errors = vec![];
check_annotations(
messages,
vec![],
Path::new("moobar"),
&mut errors,
"",
&comments,
)
.unwrap();
match &errors[..] {
[Error::CodeNotFound { code, .. }, Error::ErrorsWithoutPattern { msgs, .. }]
if **code == "prefix::E0308" && code.line().get() == 3 && msgs.len() == 1 => {}
_ => panic!("{:#?}", errors),
}
}
}

0 comments on commit 091439d

Please sign in to comment.