]> git.proxmox.com Git - rustc.git/blame - src/tools/clippy/tests/lint_message_convention.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / src / tools / clippy / tests / lint_message_convention.rs
CommitLineData
c295e0f8
XL
1#![cfg_attr(feature = "deny-warnings", deny(warnings))]
2#![warn(rust_2018_idioms, unused_lifetimes)]
3
f20569fa
XL
4use std::ffi::OsStr;
5use std::path::PathBuf;
6
7use regex::RegexSet;
8
9#[derive(Debug)]
10struct Message {
11 path: PathBuf,
12 bad_lines: Vec<String>,
13}
14
15impl Message {
16 fn new(path: PathBuf) -> Self {
17 let content: String = std::fs::read_to_string(&path).unwrap();
18 // we don't want the first letter after "error: ", "help: " ... to be capitalized
5e7ed085 19 // also no punctuation (except for "?" ?) at the end of a line
f20569fa
XL
20 let regex_set: RegexSet = RegexSet::new(&[
21 r"error: [A-Z]",
22 r"help: [A-Z]",
23 r"warning: [A-Z]",
24 r"note: [A-Z]",
25 r"try this: [A-Z]",
26 r"error: .*[.!]$",
27 r"help: .*[.!]$",
28 r"warning: .*[.!]$",
29 r"note: .*[.!]$",
30 r"try this: .*[.!]$",
31 ])
32 .unwrap();
33
34 // sometimes the first character is capitalized and it is legal (like in "C-like enum variants") or
35 // we want to ask a question ending in "?"
36 let exceptions_set: RegexSet = RegexSet::new(&[
37 r".*C-like enum variant discriminant is not portable to 32-bit targets",
38 r".*did you mean `unix`?",
39 r".*the arguments may be inverted...",
40 r".*Intel x86 assembly syntax used",
41 r".*AT&T x86 assembly syntax used",
42 r".*remove .*the return type...",
43 r"note: Clippy version: .*",
44 r"the compiler unexpectedly panicked. this is a bug.",
45 ])
46 .unwrap();
47
48 let bad_lines = content
49 .lines()
50 .filter(|line| regex_set.matches(line).matched_any())
51 // ignore exceptions
52 .filter(|line| !exceptions_set.matches(line).matched_any())
53 .map(ToOwned::to_owned)
54 .collect::<Vec<String>>();
55
56 Message { path, bad_lines }
57 }
58}
59
60#[test]
61fn lint_message_convention() {
62 // disable the test inside the rustc test suite
63 if option_env!("RUSTC_TEST_SUITE").is_some() {
64 return;
65 }
66
67 // make sure that lint messages:
68 // * are not capitalized
04454e1e 69 // * don't have punctuation at the end of the last sentence
f20569fa
XL
70
71 // these directories have interesting tests
72 let test_dirs = ["ui", "ui-cargo", "ui-internal", "ui-toml"]
73 .iter()
74 .map(PathBuf::from)
75 .map(|p| {
76 let base = PathBuf::from("tests");
77 base.join(p)
78 });
79
80 // gather all .stderr files
81 let tests = test_dirs
82 .flat_map(|dir| {
83 std::fs::read_dir(dir)
84 .expect("failed to read dir")
85 .map(|direntry| direntry.unwrap().path())
86 })
87 .filter(|file| matches!(file.extension().map(OsStr::to_str), Some(Some("stderr"))));
88
89 // get all files that have any "bad lines" in them
90 let bad_tests: Vec<Message> = tests
91 .map(Message::new)
92 .filter(|message| !message.bad_lines.is_empty())
93 .collect();
94
cdc7bbd5 95 for message in &bad_tests {
f20569fa
XL
96 eprintln!(
97 "error: the test '{}' contained the following nonconforming lines :",
98 message.path.display()
99 );
100 message.bad_lines.iter().for_each(|line| eprintln!("{}", line));
101 eprintln!("\n\n");
cdc7bbd5 102 }
f20569fa
XL
103
104 eprintln!(
105 "\n\n\nLint message should not start with a capital letter and should not have punctuation at the end of the message unless multiple sentences are needed."
106 );
107 eprintln!("Check out the rustc-dev-guide for more information:");
108 eprintln!("https://rustc-dev-guide.rust-lang.org/diagnostics.html#diagnostic-structure\n\n\n");
109
110 assert!(bad_tests.is_empty());
111}