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