mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-02 00:07:42 +03:00
clippy_dev: Parse and format lint pass macros.
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
use crate::generate::generate_lint_files;
|
||||
use crate::parse::cursor::{self, Capture, Cursor};
|
||||
use crate::parse::{ActiveLint, DeprecatedLint, Lint, LintData, LintName, ParseCx, RenamedLint};
|
||||
use crate::utils::{
|
||||
@@ -40,7 +39,7 @@ pub fn deprecate<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, name
|
||||
};
|
||||
|
||||
remove_lint_declaration(name, &prev_lint, &data, &mut FileUpdater::default());
|
||||
generate_lint_files(UpdateMode::Change, &data);
|
||||
data.gen_decls(UpdateMode::Change);
|
||||
println!("info: `{name}` has successfully been deprecated");
|
||||
println!("note: you must run `cargo uitest` to update the test results");
|
||||
}
|
||||
@@ -74,7 +73,7 @@ pub fn uplift<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_nam
|
||||
updater.update_file(e.path(), &mut update_fn);
|
||||
}
|
||||
}
|
||||
generate_lint_files(UpdateMode::Change, &data);
|
||||
data.gen_decls(UpdateMode::Change);
|
||||
println!("info: `{old_name}` has successfully been uplifted as `{new_name}`");
|
||||
println!("note: you must run `cargo uitest` to update the test results");
|
||||
}
|
||||
@@ -151,7 +150,7 @@ pub fn rename<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_nam
|
||||
updater.update_file(e.path(), &mut update_fn);
|
||||
}
|
||||
}
|
||||
generate_lint_files(UpdateMode::Change, &data);
|
||||
data.gen_decls(UpdateMode::Change);
|
||||
|
||||
println!("Renamed `{old_name}` to `{new_name}`");
|
||||
println!("All code referencing the old name has been updated");
|
||||
@@ -172,11 +171,11 @@ fn remove_lint_declaration(name: &str, lint: &ActiveLint<'_>, data: &LintData<'_
|
||||
delete_file_if_exists(lint.path.as_ref())
|
||||
} else {
|
||||
updater.update_file(&lint.path, &mut |_, src, dst| -> UpdateStatus {
|
||||
let mut start = &src[..lint.declaration_range.start];
|
||||
let mut start = &src[..lint.declaration_range.start as usize];
|
||||
if start.ends_with("\n\n") {
|
||||
start = &start[..start.len() - 1];
|
||||
}
|
||||
let mut end = &src[lint.declaration_range.end..];
|
||||
let mut end = &src[lint.declaration_range.end as usize..];
|
||||
if end.starts_with("\n\n") {
|
||||
end = &end[1..];
|
||||
}
|
||||
|
||||
+24
-3
@@ -1,6 +1,7 @@
|
||||
use crate::new_parse_cx;
|
||||
use crate::utils::{
|
||||
ErrAction, FileUpdater, UpdateMode, UpdateStatus, expect_action, run_with_output, split_args_for_threads,
|
||||
walk_dir_no_dot_or_target,
|
||||
ErrAction, FileUpdater, UpdateMode, UpdateStatus, expect_action, run_with_output, slice_groups,
|
||||
split_args_for_threads, walk_dir_no_dot_or_target,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize};
|
||||
@@ -326,10 +327,30 @@ fn run_rustfmt(update_mode: UpdateMode) {
|
||||
|
||||
// the "main" function of cargo dev fmt
|
||||
pub fn run(update_mode: UpdateMode) {
|
||||
run_rustfmt(update_mode);
|
||||
fmt_syms(update_mode);
|
||||
if let Err(e) = fmt_conf(update_mode.is_check()) {
|
||||
e.display();
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
new_parse_cx(|cx| {
|
||||
let data = cx.parse_lint_decls();
|
||||
let mut updater = FileUpdater::default();
|
||||
|
||||
for passes in slice_groups(&data.lint_passes, |head, tail| {
|
||||
tail.iter().take_while(|&x| x.path == head.path).count()
|
||||
}) {
|
||||
updater.update_file_checked("cargo dev fmt", update_mode, &passes[0].path, &mut |_, src, dst| {
|
||||
let pos = passes.iter().fold(0u32, |start, pass| {
|
||||
dst.push_str(&src[start as usize..pass.decl_range.start as usize]);
|
||||
pass.gen_mac(dst);
|
||||
pass.decl_range.end
|
||||
});
|
||||
dst.push_str(&src[pos as usize..]);
|
||||
UpdateStatus::from_changed(src != dst)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
run_rustfmt(update_mode);
|
||||
}
|
||||
|
||||
+225
-171
@@ -1,5 +1,5 @@
|
||||
use crate::parse::cursor::Cursor;
|
||||
use crate::parse::{Lint, LintData, ParseCx};
|
||||
use crate::parse::{Lint, LintData, LintPass};
|
||||
use crate::utils::{FileUpdater, UpdateMode, UpdateStatus, update_text_region_fn};
|
||||
use itertools::Itertools;
|
||||
use std::collections::HashSet;
|
||||
@@ -12,193 +12,247 @@
|
||||
|
||||
const DOCS_LINK: &str = "https://rust-lang.github.io/rust-clippy/master/index.html";
|
||||
|
||||
/// Runs the `update_lints` command.
|
||||
///
|
||||
/// This updates various generated values from the lint source code.
|
||||
///
|
||||
/// `update_mode` indicates if the files should be updated or if updates should be checked for.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if a file path could not read from or then written to
|
||||
pub fn update(cx: ParseCx<'_>, update_mode: UpdateMode) {
|
||||
let data = cx.parse_lint_decls();
|
||||
generate_lint_files(update_mode, &data);
|
||||
}
|
||||
impl LintData<'_> {
|
||||
#[expect(clippy::too_many_lines)]
|
||||
pub fn gen_decls(&self, update_mode: UpdateMode) {
|
||||
let mut updater = FileUpdater::default();
|
||||
|
||||
#[expect(clippy::too_many_lines)]
|
||||
pub fn generate_lint_files(update_mode: UpdateMode, data: &LintData<'_>) {
|
||||
let mut updater = FileUpdater::default();
|
||||
|
||||
let mut lints: Vec<_> = data.lints.iter().map(|(&x, y)| (x, y)).collect();
|
||||
lints.sort_by_key(|&(x, _)| x);
|
||||
updater.update_file_checked(
|
||||
"cargo dev update_lints",
|
||||
update_mode,
|
||||
"CHANGELOG.md",
|
||||
&mut update_text_region_fn(
|
||||
"<!-- begin autogenerated links to lint list -->\n",
|
||||
"<!-- end autogenerated links to lint list -->",
|
||||
|dst| {
|
||||
for &(lint, _) in &lints {
|
||||
writeln!(dst, "[`{lint}`]: {DOCS_LINK}#{lint}").unwrap();
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
let mut active = Vec::with_capacity(lints.len());
|
||||
let mut deprecated = Vec::with_capacity(lints.len() / 8);
|
||||
let mut renamed = Vec::with_capacity(lints.len() / 8);
|
||||
for &(name, lint) in &lints {
|
||||
match lint {
|
||||
Lint::Active(lint) => active.push((name, lint)),
|
||||
Lint::Deprecated(lint) => deprecated.push((name, lint)),
|
||||
Lint::Renamed(lint) => renamed.push((name, lint)),
|
||||
}
|
||||
}
|
||||
active.sort_by_key(|&(_, lint)| lint.module);
|
||||
|
||||
// Round to avoid updating the readme every time a lint is added/deprecated.
|
||||
let lint_count = active.len() / 50 * 50;
|
||||
updater.update_file_checked(
|
||||
"cargo dev update_lints",
|
||||
update_mode,
|
||||
"README.md",
|
||||
&mut update_text_region_fn("[There are over ", " lints included in this crate!]", |dst| {
|
||||
write!(dst, "{lint_count}").unwrap();
|
||||
}),
|
||||
);
|
||||
updater.update_file_checked(
|
||||
"cargo dev update_lints",
|
||||
update_mode,
|
||||
"book/src/README.md",
|
||||
&mut update_text_region_fn("[There are over ", " lints included in this crate!]", |dst| {
|
||||
write!(dst, "{lint_count}").unwrap();
|
||||
}),
|
||||
);
|
||||
|
||||
updater.update_file_checked(
|
||||
"cargo dev update_lints",
|
||||
update_mode,
|
||||
"clippy_lints/src/deprecated_lints.rs",
|
||||
&mut |_, src, dst| {
|
||||
let mut cursor = Cursor::new(src);
|
||||
assert!(
|
||||
cursor.find_ident("declare_with_version").is_some()
|
||||
&& cursor.find_ident("declare_with_version").is_some(),
|
||||
"error reading deprecated lints"
|
||||
);
|
||||
dst.push_str(&src[..cursor.pos() as usize]);
|
||||
dst.push_str("! { DEPRECATED(DEPRECATED_VERSION) = [\n");
|
||||
for &(name, data) in &deprecated {
|
||||
write!(
|
||||
dst,
|
||||
" #[clippy::version = \"{}\"]\n (\"clippy::{name}\", \"{}\"),\n",
|
||||
data.version, data.reason,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
dst.push_str(
|
||||
"]}\n\n\
|
||||
#[rustfmt::skip]\n\
|
||||
declare_with_version! { RENAMED(RENAMED_VERSION) = [\n\
|
||||
",
|
||||
);
|
||||
for &(name, data) in &renamed {
|
||||
write!(
|
||||
dst,
|
||||
" #[clippy::version = \"{}\"]\n (\"clippy::{name}\", \"{}\"),\n",
|
||||
data.version, data.new_name,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
dst.push_str("]}\n");
|
||||
UpdateStatus::from_changed(src != dst)
|
||||
},
|
||||
);
|
||||
updater.update_file_checked(
|
||||
"cargo dev update_lints",
|
||||
update_mode,
|
||||
"tests/ui/deprecated.rs",
|
||||
&mut |_, src, dst| {
|
||||
dst.push_str(GENERATED_FILE_COMMENT);
|
||||
for &(lint, _) in &deprecated {
|
||||
writeln!(dst, "#![warn(clippy::{lint})] //~ ERROR: lint `clippy::{lint}`").unwrap();
|
||||
}
|
||||
dst.push_str("\nfn main() {}\n");
|
||||
UpdateStatus::from_changed(src != dst)
|
||||
},
|
||||
);
|
||||
updater.update_file_checked(
|
||||
"cargo dev update_lints",
|
||||
update_mode,
|
||||
"tests/ui/rename.rs",
|
||||
&mut move |_, src, dst| {
|
||||
let mut seen_lints = HashSet::new();
|
||||
dst.push_str(GENERATED_FILE_COMMENT);
|
||||
dst.push_str("#![allow(clippy::duplicated_attributes)]\n");
|
||||
for &(_, lint) in &renamed {
|
||||
if seen_lints.insert(lint.new_name) {
|
||||
writeln!(dst, "#![allow({})]", lint.new_name).unwrap();
|
||||
}
|
||||
}
|
||||
for &(lint, _) in &renamed {
|
||||
writeln!(dst, "#![warn(clippy::{lint})] //~ ERROR: lint `clippy::{lint}`").unwrap();
|
||||
}
|
||||
dst.push_str("\nfn main() {}\n");
|
||||
UpdateStatus::from_changed(src != dst)
|
||||
},
|
||||
);
|
||||
for (crate_name, lints) in active.iter().copied().into_group_map_by(|&(_, lint)| {
|
||||
let Some(path::Component::Normal(name)) = lint.path.components().next() else {
|
||||
// All paths should start with `{crate_name}/src` when parsed from `find_lint_decls`
|
||||
panic!(
|
||||
"internal error: can't read crate name from path `{}`",
|
||||
lint.path.display()
|
||||
);
|
||||
};
|
||||
name
|
||||
}) {
|
||||
let mut lints: Vec<_> = self.lints.iter().map(|(&x, y)| (x, y)).collect();
|
||||
lints.sort_by_key(|&(x, _)| x);
|
||||
updater.update_file_checked(
|
||||
"cargo dev update_lints",
|
||||
update_mode,
|
||||
Path::new(crate_name).join("src/lib.rs"),
|
||||
"CHANGELOG.md",
|
||||
&mut update_text_region_fn(
|
||||
"// begin lints modules, do not remove this comment, it's used in `update_lints`\n",
|
||||
"// end lints modules, do not remove this comment, it's used in `update_lints`",
|
||||
"<!-- begin autogenerated links to lint list -->\n",
|
||||
"<!-- end autogenerated links to lint list -->",
|
||||
|dst| {
|
||||
let mut prev = "";
|
||||
for &(_, lint) in &lints {
|
||||
if lint.module != prev {
|
||||
writeln!(dst, "mod {};", lint.module).unwrap();
|
||||
prev = lint.module;
|
||||
}
|
||||
for &(lint, _) in &lints {
|
||||
writeln!(dst, "[`{lint}`]: {DOCS_LINK}#{lint}").unwrap();
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
let mut active = Vec::with_capacity(lints.len());
|
||||
let mut deprecated = Vec::with_capacity(lints.len() / 8);
|
||||
let mut renamed = Vec::with_capacity(lints.len() / 8);
|
||||
for &(name, lint) in &lints {
|
||||
match lint {
|
||||
Lint::Active(lint) => active.push((name, lint)),
|
||||
Lint::Deprecated(lint) => deprecated.push((name, lint)),
|
||||
Lint::Renamed(lint) => renamed.push((name, lint)),
|
||||
}
|
||||
}
|
||||
active.sort_by_key(|&(_, lint)| lint.module);
|
||||
|
||||
// Round to avoid updating the readme every time a lint is added/deprecated.
|
||||
let lint_count = active.len() / 50 * 50;
|
||||
updater.update_file_checked(
|
||||
"cargo dev update_lints",
|
||||
update_mode,
|
||||
Path::new(crate_name).join("src/declared_lints.rs"),
|
||||
"README.md",
|
||||
&mut update_text_region_fn("[There are over ", " lints included in this crate!]", |dst| {
|
||||
write!(dst, "{lint_count}").unwrap();
|
||||
}),
|
||||
);
|
||||
updater.update_file_checked(
|
||||
"cargo dev update_lints",
|
||||
update_mode,
|
||||
"book/src/README.md",
|
||||
&mut update_text_region_fn("[There are over ", " lints included in this crate!]", |dst| {
|
||||
write!(dst, "{lint_count}").unwrap();
|
||||
}),
|
||||
);
|
||||
|
||||
updater.update_file_checked(
|
||||
"cargo dev update_lints",
|
||||
update_mode,
|
||||
"clippy_lints/src/deprecated_lints.rs",
|
||||
&mut |_, src, dst| {
|
||||
dst.push_str(GENERATED_FILE_COMMENT);
|
||||
dst.push_str("pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[\n");
|
||||
let mut buf = String::new();
|
||||
for &(name, lint) in &lints {
|
||||
buf.clear();
|
||||
buf.push_str(name);
|
||||
buf.make_ascii_uppercase();
|
||||
if lint.module.is_empty() {
|
||||
writeln!(dst, " crate::{buf}_INFO,").unwrap();
|
||||
} else {
|
||||
writeln!(dst, " crate::{}::{buf}_INFO,", lint.module).unwrap();
|
||||
}
|
||||
let mut cursor = Cursor::new(src);
|
||||
assert!(
|
||||
cursor.find_ident("declare_with_version").is_some()
|
||||
&& cursor.find_ident("declare_with_version").is_some(),
|
||||
"error reading deprecated lints"
|
||||
);
|
||||
dst.push_str(&src[..cursor.pos() as usize]);
|
||||
dst.push_str("! { DEPRECATED(DEPRECATED_VERSION) = [\n");
|
||||
for &(name, data) in &deprecated {
|
||||
write!(
|
||||
dst,
|
||||
" #[clippy::version = \"{}\"]\n (\"clippy::{name}\", \"{}\"),\n",
|
||||
data.version, data.reason,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
dst.push_str("];\n");
|
||||
dst.push_str(
|
||||
"]}\n\n\
|
||||
#[rustfmt::skip]\n\
|
||||
declare_with_version! { RENAMED(RENAMED_VERSION) = [\n\
|
||||
",
|
||||
);
|
||||
for &(name, data) in &renamed {
|
||||
write!(
|
||||
dst,
|
||||
" #[clippy::version = \"{}\"]\n (\"clippy::{name}\", \"{}\"),\n",
|
||||
data.version, data.new_name,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
dst.push_str("]}\n");
|
||||
UpdateStatus::from_changed(src != dst)
|
||||
},
|
||||
);
|
||||
updater.update_file_checked(
|
||||
"cargo dev update_lints",
|
||||
update_mode,
|
||||
"tests/ui/deprecated.rs",
|
||||
&mut |_, src, dst| {
|
||||
dst.push_str(GENERATED_FILE_COMMENT);
|
||||
for &(lint, _) in &deprecated {
|
||||
writeln!(dst, "#![warn(clippy::{lint})] //~ ERROR: lint `clippy::{lint}`").unwrap();
|
||||
}
|
||||
dst.push_str("\nfn main() {}\n");
|
||||
UpdateStatus::from_changed(src != dst)
|
||||
},
|
||||
);
|
||||
updater.update_file_checked(
|
||||
"cargo dev update_lints",
|
||||
update_mode,
|
||||
"tests/ui/rename.rs",
|
||||
&mut move |_, src, dst| {
|
||||
let mut seen_lints = HashSet::new();
|
||||
dst.push_str(GENERATED_FILE_COMMENT);
|
||||
dst.push_str("#![allow(clippy::duplicated_attributes)]\n");
|
||||
for &(_, lint) in &renamed {
|
||||
if seen_lints.insert(lint.new_name) {
|
||||
writeln!(dst, "#![allow({})]", lint.new_name).unwrap();
|
||||
}
|
||||
}
|
||||
for &(lint, _) in &renamed {
|
||||
writeln!(dst, "#![warn(clippy::{lint})] //~ ERROR: lint `clippy::{lint}`").unwrap();
|
||||
}
|
||||
dst.push_str("\nfn main() {}\n");
|
||||
UpdateStatus::from_changed(src != dst)
|
||||
},
|
||||
);
|
||||
for (crate_name, lints) in active.iter().copied().into_group_map_by(|&(_, lint)| {
|
||||
let Some(path::Component::Normal(name)) = lint.path.components().next() else {
|
||||
// All paths should start with `{crate_name}/src` when parsed from `find_lint_decls`
|
||||
panic!(
|
||||
"internal error: can't read crate name from path `{}`",
|
||||
lint.path.display()
|
||||
);
|
||||
};
|
||||
name
|
||||
}) {
|
||||
updater.update_file_checked(
|
||||
"cargo dev update_lints",
|
||||
update_mode,
|
||||
Path::new(crate_name).join("src/lib.rs"),
|
||||
&mut update_text_region_fn(
|
||||
"// begin lints modules, do not remove this comment, it's used in `update_lints`\n",
|
||||
"// end lints modules, do not remove this comment, it's used in `update_lints`",
|
||||
|dst| {
|
||||
let mut prev = "";
|
||||
for &(_, lint) in &lints {
|
||||
if lint.module != prev {
|
||||
writeln!(dst, "mod {};", lint.module).unwrap();
|
||||
prev = lint.module;
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
updater.update_file_checked(
|
||||
"cargo dev update_lints",
|
||||
update_mode,
|
||||
Path::new(crate_name).join("src/declared_lints.rs"),
|
||||
&mut |_, src, dst| {
|
||||
dst.push_str(GENERATED_FILE_COMMENT);
|
||||
dst.push_str("pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[\n");
|
||||
let mut buf = String::new();
|
||||
for &(name, lint) in &lints {
|
||||
buf.clear();
|
||||
buf.push_str(name);
|
||||
buf.make_ascii_uppercase();
|
||||
if lint.module.is_empty() {
|
||||
writeln!(dst, " crate::{buf}_INFO,").unwrap();
|
||||
} else {
|
||||
writeln!(dst, " crate::{}::{buf}_INFO,", lint.module).unwrap();
|
||||
}
|
||||
}
|
||||
dst.push_str("];\n");
|
||||
UpdateStatus::from_changed(src != dst)
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LintPass<'_> {
|
||||
pub fn gen_mac(&self, dst: &mut String) {
|
||||
let mut line_start = dst.len();
|
||||
dst.extend([self.mac.name(), "!("]);
|
||||
let has_docs = write_comment_lines(self.docs, "\n ", dst);
|
||||
let (list_indent, list_multi_end, end) = if has_docs {
|
||||
dst.push_str("\n ");
|
||||
line_start = dst.len() - 4;
|
||||
(" ", "\n ", "]\n);")
|
||||
} else {
|
||||
(" ", "\n", "]);")
|
||||
};
|
||||
dst.push_str(self.name);
|
||||
if let Some(lt) = self.lt {
|
||||
dst.extend(["<", lt, ">"]);
|
||||
}
|
||||
dst.push_str(" => [");
|
||||
let fmt = write_list(
|
||||
self.lints.iter().copied(),
|
||||
80usize.saturating_sub(dst.len() - line_start),
|
||||
list_indent,
|
||||
dst,
|
||||
);
|
||||
if matches!(fmt, ListFmt::MultiLine) {
|
||||
dst.push_str(list_multi_end);
|
||||
}
|
||||
dst.push_str(end);
|
||||
}
|
||||
}
|
||||
|
||||
fn write_comment_lines(s: &str, prefix: &str, dst: &mut String) -> bool {
|
||||
let mut has_doc = false;
|
||||
for line in s.split('\n') {
|
||||
let line = line.trim_start();
|
||||
if !line.is_empty() {
|
||||
has_doc = true;
|
||||
dst.extend([prefix, line]);
|
||||
}
|
||||
}
|
||||
has_doc
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum ListFmt {
|
||||
SingleLine,
|
||||
MultiLine,
|
||||
}
|
||||
|
||||
fn write_list<'a>(
|
||||
items: impl Iterator<Item = &'a str> + Clone,
|
||||
single_line_limit: usize,
|
||||
indent: &str,
|
||||
dst: &mut String,
|
||||
) -> ListFmt {
|
||||
let len = items.clone().map(str::len).sum::<usize>();
|
||||
if len > single_line_limit {
|
||||
for item in items {
|
||||
dst.extend(["\n", indent, item, ","]);
|
||||
}
|
||||
ListFmt::MultiLine
|
||||
} else {
|
||||
let _ = write!(dst, "{}", items.format(", "));
|
||||
ListFmt::SingleLine
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
pub mod dogfood;
|
||||
pub mod edit_lints;
|
||||
pub mod fmt;
|
||||
pub mod generate;
|
||||
pub mod lint;
|
||||
pub mod new_lint;
|
||||
pub mod release;
|
||||
@@ -35,6 +34,7 @@
|
||||
pub mod setup;
|
||||
pub mod sync;
|
||||
|
||||
mod generate;
|
||||
mod parse;
|
||||
mod utils;
|
||||
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
use clippy_dev::{
|
||||
ClippyInfo, UpdateMode, dogfood, edit_lints, fmt, generate, lint, new_lint, new_parse_cx, release, serve, setup,
|
||||
sync,
|
||||
ClippyInfo, UpdateMode, dogfood, edit_lints, fmt, lint, new_lint, new_parse_cx, release, serve, setup, sync,
|
||||
};
|
||||
use std::env;
|
||||
|
||||
@@ -28,7 +27,7 @@ fn main() {
|
||||
} => dogfood::dogfood(fix, allow_dirty, allow_staged, allow_no_vcs),
|
||||
DevCommand::Fmt { check } => fmt::run(UpdateMode::from_check(check)),
|
||||
DevCommand::UpdateLints { check } => {
|
||||
new_parse_cx(|cx| generate::generate_lint_files(UpdateMode::from_check(check), &cx.parse_lint_decls()));
|
||||
new_parse_cx(|cx| cx.parse_lint_decls().gen_decls(UpdateMode::from_check(check)));
|
||||
},
|
||||
DevCommand::NewLint {
|
||||
pass,
|
||||
@@ -37,7 +36,7 @@ fn main() {
|
||||
r#type,
|
||||
msrv,
|
||||
} => match new_lint::create(clippy.version, pass, &name, &category, r#type.as_deref(), msrv) {
|
||||
Ok(()) => new_parse_cx(|cx| generate::generate_lint_files(UpdateMode::Change, &cx.parse_lint_decls())),
|
||||
Ok(()) => new_parse_cx(|cx| cx.parse_lint_decls().gen_decls(UpdateMode::Change)),
|
||||
Err(e) => eprintln!("Unable to create lint: {e}"),
|
||||
},
|
||||
DevCommand::Setup(SetupCommand { subcommand }) => match subcommand {
|
||||
|
||||
+141
-20
@@ -13,6 +13,7 @@
|
||||
pub struct ParseCxImpl<'cx> {
|
||||
pub arena: &'cx DroplessArena,
|
||||
pub str_buf: StrBuf,
|
||||
pub str_list_buf: VecBuf<&'cx str>,
|
||||
}
|
||||
pub type ParseCx<'cx> = &'cx mut ParseCxImpl<'cx>;
|
||||
|
||||
@@ -22,6 +23,7 @@ pub fn new_parse_cx<'env, T>(f: impl for<'cx> FnOnce(&'cx mut Scoped<'cx, 'env,
|
||||
f(&mut Scoped::new(ParseCxImpl {
|
||||
arena: &arena,
|
||||
str_buf: StrBuf::with_capacity(128),
|
||||
str_list_buf: VecBuf::with_capacity(128),
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -82,6 +84,20 @@ pub fn with<T>(&mut self, f: impl FnOnce(&mut String) -> T) -> T {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VecBuf<T>(Vec<T>);
|
||||
impl<T> VecBuf<T> {
|
||||
/// Creates a new buffer with the specified initial capacity.
|
||||
pub fn with_capacity(cap: usize) -> Self {
|
||||
Self(Vec::with_capacity(cap))
|
||||
}
|
||||
|
||||
/// Performs an operation with the freshly cleared buffer.
|
||||
pub fn with<R>(&mut self, f: impl FnOnce(&mut Vec<T>) -> R) -> R {
|
||||
self.0.clear();
|
||||
f(&mut self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum LintTool {
|
||||
Rustc,
|
||||
@@ -128,7 +144,7 @@ pub struct ActiveLint<'cx> {
|
||||
pub group: &'cx str,
|
||||
pub module: &'cx str,
|
||||
pub path: PathBuf,
|
||||
pub declaration_range: Range<usize>,
|
||||
pub declaration_range: Range<u32>,
|
||||
}
|
||||
|
||||
pub struct DeprecatedLint<'cx> {
|
||||
@@ -147,8 +163,35 @@ pub enum Lint<'cx> {
|
||||
Renamed(RenamedLint<'cx>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum LintPassMac {
|
||||
Declare,
|
||||
Impl,
|
||||
}
|
||||
impl LintPassMac {
|
||||
pub fn name(self) -> &'static str {
|
||||
match self {
|
||||
Self::Declare => "declare_lint_pass",
|
||||
Self::Impl => "impl_lint_pass",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LintPass<'cx> {
|
||||
/// The raw text of the documentation comments. May include leading/trailing
|
||||
/// whitespace and empty lines.
|
||||
pub docs: &'cx str,
|
||||
pub name: &'cx str,
|
||||
pub lt: Option<&'cx str>,
|
||||
pub mac: LintPassMac,
|
||||
pub decl_range: Range<u32>,
|
||||
pub lints: &'cx [&'cx str],
|
||||
pub path: PathBuf,
|
||||
}
|
||||
|
||||
pub struct LintData<'cx> {
|
||||
pub lints: FxHashMap<&'cx str, Lint<'cx>>,
|
||||
pub lint_passes: Vec<LintPass<'cx>>,
|
||||
}
|
||||
|
||||
impl<'cx> ParseCxImpl<'cx> {
|
||||
@@ -158,6 +201,7 @@ pub fn parse_lint_decls(&mut self) -> LintData<'cx> {
|
||||
let mut data = LintData {
|
||||
#[expect(clippy::default_trait_access)]
|
||||
lints: FxHashMap::with_capacity_and_hasher(1000, Default::default()),
|
||||
lint_passes: Vec::with_capacity(400),
|
||||
};
|
||||
|
||||
let mut contents = String::new();
|
||||
@@ -193,7 +237,7 @@ pub fn parse_lint_decls(&mut self) -> LintData<'cx> {
|
||||
self.str_buf
|
||||
.alloc_replaced(self.arena, path, path::MAIN_SEPARATOR, "::")
|
||||
};
|
||||
self.parse_clippy_lint_decls(
|
||||
self.parse_lint_src_file(
|
||||
e.path(),
|
||||
File::open_read_to_cleared_string(e.path(), &mut contents),
|
||||
module,
|
||||
@@ -208,11 +252,11 @@ pub fn parse_lint_decls(&mut self) -> LintData<'cx> {
|
||||
}
|
||||
|
||||
/// Parse a source file looking for `declare_clippy_lint` macro invocations.
|
||||
fn parse_clippy_lint_decls(&mut self, path: &Path, contents: &str, module: &'cx str, data: &mut LintData<'cx>) {
|
||||
fn parse_lint_src_file(&mut self, path: &Path, contents: &str, module: &'cx str, data: &mut LintData<'cx>) {
|
||||
#[allow(clippy::enum_glob_use)]
|
||||
use cursor::Pat::*;
|
||||
#[rustfmt::skip]
|
||||
static DECL_TOKENS: &[cursor::Pat<'_>] = &[
|
||||
static LINT_DECL_TOKENS: &[cursor::Pat<'_>] = &[
|
||||
// !{ /// docs
|
||||
Bang, OpenBrace, AnyComment,
|
||||
// #[clippy::version = "version"]
|
||||
@@ -220,24 +264,101 @@ fn parse_clippy_lint_decls(&mut self, path: &Path, contents: &str, module: &'cx
|
||||
// pub NAME, GROUP,
|
||||
Ident("pub"), CaptureIdent, Comma, AnyComment, CaptureIdent, Comma,
|
||||
];
|
||||
#[rustfmt::skip]
|
||||
static PASS_DECL_TOKENS: &[cursor::Pat<'_>] = &[
|
||||
// !( NAME <'lt> => [
|
||||
Bang, OpenParen, CaptureDocLines, CaptureIdent, CaptureOptLifetimeArg, FatArrow, OpenBracket,
|
||||
];
|
||||
|
||||
let mut cursor = Cursor::new(contents);
|
||||
let mut captures = [Capture::EMPTY; 2];
|
||||
while let Some(start) = cursor.find_ident("declare_clippy_lint") {
|
||||
if cursor.match_all(DECL_TOKENS, &mut captures) && cursor.find_pat(CloseBrace) {
|
||||
assert!(
|
||||
data.lints
|
||||
.insert(
|
||||
self.str_buf.alloc_ascii_lower(self.arena, cursor.get_text(captures[0])),
|
||||
Lint::Active(ActiveLint {
|
||||
group: self.arena.alloc_str(cursor.get_text(captures[1])),
|
||||
module,
|
||||
path: path.into(),
|
||||
declaration_range: start as usize..cursor.pos() as usize,
|
||||
}),
|
||||
)
|
||||
.is_none()
|
||||
);
|
||||
let mut captures = [Capture::EMPTY; 3];
|
||||
while let Some(mac_name) = cursor.find_any_ident() {
|
||||
match cursor.get_text(mac_name) {
|
||||
"declare_clippy_lint"
|
||||
if cursor.match_all(LINT_DECL_TOKENS, &mut captures) && cursor.find_pat(CloseBrace) =>
|
||||
{
|
||||
assert!(
|
||||
data.lints
|
||||
.insert(
|
||||
self.str_buf.alloc_ascii_lower(self.arena, cursor.get_text(captures[0])),
|
||||
Lint::Active(ActiveLint {
|
||||
group: self.arena.alloc_str(cursor.get_text(captures[1])),
|
||||
module,
|
||||
path: path.into(),
|
||||
declaration_range: mac_name.pos..cursor.pos(),
|
||||
}),
|
||||
)
|
||||
.is_none()
|
||||
);
|
||||
},
|
||||
mac @ ("declare_lint_pass" | "impl_lint_pass") if cursor.match_all(PASS_DECL_TOKENS, &mut captures) => {
|
||||
let mac = if matches!(mac, "declare_lint_pass") {
|
||||
LintPassMac::Declare
|
||||
} else {
|
||||
LintPassMac::Impl
|
||||
};
|
||||
let docs = match cursor.get_text(captures[0]) {
|
||||
"" => "",
|
||||
x => self.arena.alloc_str(x),
|
||||
};
|
||||
let name = self.arena.alloc_str(cursor.get_text(captures[1]));
|
||||
let lt = cursor.get_text(captures[2]);
|
||||
let lt = if lt.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(self.arena.alloc_str(lt))
|
||||
};
|
||||
|
||||
let lints = self.str_list_buf.with(|buf| {
|
||||
// Parses a comma separated list of paths and converts each path
|
||||
// to a string with whitespace removed.
|
||||
while !cursor.match_pat(CloseBracket) {
|
||||
buf.push(self.str_buf.with(|buf| {
|
||||
if cursor.match_pat(DoubleColon) {
|
||||
buf.push_str("::");
|
||||
}
|
||||
let capture = cursor.capture_ident()?;
|
||||
buf.push_str(cursor.get_text(capture));
|
||||
while cursor.match_pat(DoubleColon) {
|
||||
buf.push_str("::");
|
||||
let capture = cursor.capture_ident()?;
|
||||
buf.push_str(cursor.get_text(capture));
|
||||
}
|
||||
Some(self.arena.alloc_str(buf))
|
||||
})?);
|
||||
|
||||
if !cursor.match_pat(Comma) {
|
||||
if !cursor.match_pat(CloseBracket) {
|
||||
return None;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// The arena panics when allocating a size of zero.
|
||||
Some(if buf.is_empty() {
|
||||
&[]
|
||||
} else {
|
||||
buf.sort_unstable();
|
||||
&*self.arena.alloc_slice(buf)
|
||||
})
|
||||
});
|
||||
|
||||
if let Some(lints) = lints
|
||||
&& cursor.match_all(&[CloseParen, Semi], &mut [])
|
||||
{
|
||||
data.lint_passes.push(LintPass {
|
||||
docs,
|
||||
name,
|
||||
lt,
|
||||
mac,
|
||||
decl_range: mac_name.pos..cursor.pos(),
|
||||
lints,
|
||||
path: path.into(),
|
||||
});
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ pub enum Pat<'a> {
|
||||
/// Matches any number of comments and doc comments.
|
||||
AnyComment,
|
||||
Ident(&'a str),
|
||||
CaptureDocLines,
|
||||
CaptureIdent,
|
||||
LitStr,
|
||||
CaptureLitStr,
|
||||
@@ -22,12 +23,14 @@ pub enum Pat<'a> {
|
||||
Comma,
|
||||
DoubleColon,
|
||||
Eq,
|
||||
FatArrow,
|
||||
Lifetime,
|
||||
Lt,
|
||||
Gt,
|
||||
OpenBrace,
|
||||
OpenBracket,
|
||||
OpenParen,
|
||||
CaptureOptLifetimeArg,
|
||||
Pound,
|
||||
Semi,
|
||||
}
|
||||
@@ -112,6 +115,7 @@ pub fn step(&mut self) {
|
||||
///
|
||||
/// For each capture made by the pattern one item will be taken from the capture
|
||||
/// sequence with the result placed inside.
|
||||
#[expect(clippy::too_many_lines)]
|
||||
fn match_impl(&mut self, pat: Pat<'_>, captures: &mut slice::IterMut<'_, Capture>) -> bool {
|
||||
loop {
|
||||
match (pat, self.next_token.kind) {
|
||||
@@ -121,7 +125,6 @@ fn match_impl(&mut self, pat: Pat<'_>, captures: &mut slice::IterMut<'_, Capture
|
||||
Pat::AnyComment,
|
||||
TokenKind::BlockComment { terminated: true, .. } | TokenKind::LineComment { .. },
|
||||
) => self.step(),
|
||||
(Pat::AnyComment, _) => return true,
|
||||
(Pat::Bang, TokenKind::Bang)
|
||||
| (Pat::CloseBrace, TokenKind::CloseBrace)
|
||||
| (Pat::CloseBracket, TokenKind::CloseBracket)
|
||||
@@ -152,12 +155,48 @@ fn match_impl(&mut self, pat: Pat<'_>, captures: &mut slice::IterMut<'_, Capture
|
||||
},
|
||||
(Pat::DoubleColon, TokenKind::Colon) => {
|
||||
self.step();
|
||||
if !self.at_end() && matches!(self.next_token.kind, TokenKind::Colon) {
|
||||
if matches!(self.next_token.kind, TokenKind::Colon) {
|
||||
self.step();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
(Pat::FatArrow, TokenKind::Eq) => {
|
||||
self.step();
|
||||
if matches!(self.next_token.kind, TokenKind::Gt) {
|
||||
self.step();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
(Pat::CaptureOptLifetimeArg, TokenKind::Lt) => {
|
||||
self.step();
|
||||
loop {
|
||||
match self.next_token.kind {
|
||||
TokenKind::Lifetime { .. } => break,
|
||||
TokenKind::Whitespace => self.step(),
|
||||
_ => return false,
|
||||
}
|
||||
}
|
||||
*captures.next().unwrap() = Capture {
|
||||
pos: self.pos,
|
||||
len: self.next_token.len,
|
||||
};
|
||||
self.step();
|
||||
loop {
|
||||
match self.next_token.kind {
|
||||
TokenKind::Gt => break,
|
||||
TokenKind::Whitespace => self.step(),
|
||||
_ => return false,
|
||||
}
|
||||
}
|
||||
self.step();
|
||||
return true;
|
||||
},
|
||||
(Pat::CaptureOptLifetimeArg, _) => {
|
||||
*captures.next().unwrap() = Capture { pos: 0, len: 0 };
|
||||
return true;
|
||||
},
|
||||
#[rustfmt::skip]
|
||||
(
|
||||
Pat::CaptureLitStr,
|
||||
@@ -173,6 +212,28 @@ fn match_impl(&mut self, pat: Pat<'_>, captures: &mut slice::IterMut<'_, Capture
|
||||
self.step();
|
||||
return true;
|
||||
},
|
||||
(Pat::CaptureDocLines, TokenKind::LineComment { doc_style: Some(_) }) => {
|
||||
let pos = self.pos;
|
||||
loop {
|
||||
self.step();
|
||||
if !matches!(
|
||||
self.next_token.kind,
|
||||
TokenKind::Whitespace | TokenKind::LineComment { doc_style: Some(_) }
|
||||
) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*captures.next().unwrap() = Capture {
|
||||
pos,
|
||||
len: self.pos - pos,
|
||||
};
|
||||
return true;
|
||||
},
|
||||
(Pat::CaptureDocLines, _) => {
|
||||
*captures.next().unwrap() = Capture::EMPTY;
|
||||
return true;
|
||||
},
|
||||
(Pat::AnyComment, _) => return true,
|
||||
_ => return false,
|
||||
}
|
||||
}
|
||||
@@ -219,8 +280,8 @@ pub fn find_any_ident(&mut self) -> Option<Capture> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Consume the returns the position of the next non-whitespace token if it's an
|
||||
/// identifier. Returns `None` otherwise.
|
||||
/// Consume the returns the position of the next non-whitespace token if it's the
|
||||
/// specified identifier. Returns `None` otherwise.
|
||||
pub fn match_ident(&mut self, s: &str) -> Option<u32> {
|
||||
loop {
|
||||
match self.next_token.kind {
|
||||
@@ -235,6 +296,23 @@ pub fn match_ident(&mut self, s: &str) -> Option<u32> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Consumes and captures the next non-whitespace token if it's an identifier. Returns
|
||||
/// `None` otherwise.
|
||||
pub fn capture_ident(&mut self) -> Option<Capture> {
|
||||
loop {
|
||||
match self.next_token.kind {
|
||||
TokenKind::Ident => {
|
||||
let pos = self.pos;
|
||||
let len = self.next_token.len;
|
||||
self.step();
|
||||
return Some(Capture { pos, len });
|
||||
},
|
||||
TokenKind::Whitespace => self.step(),
|
||||
_ => return None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Continually attempt to match the pattern on subsequent tokens until a match is
|
||||
/// found. Returns whether the pattern was successfully matched.
|
||||
///
|
||||
|
||||
@@ -600,3 +600,27 @@ pub fn walk_dir_no_dot_or_target(p: impl AsRef<Path>) -> impl Iterator<Item = ::
|
||||
.is_none_or(|x| x != "target" && x.as_encoded_bytes().first().copied() != Some(b'.'))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn slice_groups<'a, T>(
|
||||
slice: &'a [T],
|
||||
split_idx: impl FnMut(&'a T, &'a [T]) -> usize,
|
||||
) -> impl Iterator<Item = &'a [T]> {
|
||||
struct I<'a, T, F> {
|
||||
slice: &'a [T],
|
||||
split_idx: F,
|
||||
}
|
||||
impl<'a, T, F: FnMut(&'a T, &'a [T]) -> usize> Iterator for I<'a, T, F> {
|
||||
type Item = &'a [T];
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let (head, tail) = self.slice.split_first()?;
|
||||
if let Some((head, tail)) = self.slice.split_at_checked((self.split_idx)(head, tail) + 1) {
|
||||
self.slice = tail;
|
||||
Some(head)
|
||||
} else {
|
||||
self.slice = &[];
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
I { slice, split_idx }
|
||||
}
|
||||
|
||||
@@ -482,10 +482,7 @@ pub struct Attributes {
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl_lint_pass!(Attributes => [
|
||||
INLINE_ALWAYS,
|
||||
REPR_PACKED_WITHOUT_ABI,
|
||||
]);
|
||||
impl_lint_pass!(Attributes => [INLINE_ALWAYS, REPR_PACKED_WITHOUT_ABI]);
|
||||
|
||||
impl Attributes {
|
||||
pub fn new(conf: &'static Conf) -> Self {
|
||||
@@ -531,8 +528,8 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
|
||||
impl_lint_pass!(EarlyAttributes => [
|
||||
DEPRECATED_CFG_ATTR,
|
||||
NON_MINIMAL_CFG,
|
||||
DEPRECATED_CLIPPY_CFG_ATTR,
|
||||
NON_MINIMAL_CFG,
|
||||
UNNECESSARY_CLIPPY_CFG,
|
||||
]);
|
||||
|
||||
@@ -561,13 +558,13 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
impl_lint_pass!(PostExpansionEarlyAttributes => [
|
||||
ALLOW_ATTRIBUTES,
|
||||
ALLOW_ATTRIBUTES_WITHOUT_REASON,
|
||||
DEPRECATED_SEMVER,
|
||||
IGNORE_WITHOUT_REASON,
|
||||
USELESS_ATTRIBUTE,
|
||||
BLANKET_CLIPPY_RESTRICTION_LINTS,
|
||||
SHOULD_PANIC_WITHOUT_EXPECT,
|
||||
MIXED_ATTRIBUTES_STYLE,
|
||||
DEPRECATED_SEMVER,
|
||||
DUPLICATED_ATTRIBUTES,
|
||||
IGNORE_WITHOUT_REASON,
|
||||
MIXED_ATTRIBUTES_STYLE,
|
||||
SHOULD_PANIC_WITHOUT_EXPECT,
|
||||
USELESS_ATTRIBUTE,
|
||||
]);
|
||||
|
||||
impl EarlyLintPass for PostExpansionEarlyAttributes {
|
||||
|
||||
@@ -171,7 +171,11 @@
|
||||
"holding a type across an await point which is not allowed to be held as per the configuration"
|
||||
}
|
||||
|
||||
impl_lint_pass!(AwaitHolding => [AWAIT_HOLDING_LOCK, AWAIT_HOLDING_REFCELL_REF, AWAIT_HOLDING_INVALID_TYPE]);
|
||||
impl_lint_pass!(AwaitHolding => [
|
||||
AWAIT_HOLDING_INVALID_TYPE,
|
||||
AWAIT_HOLDING_LOCK,
|
||||
AWAIT_HOLDING_REFCELL_REF,
|
||||
]);
|
||||
|
||||
pub struct AwaitHolding {
|
||||
def_ids: DefIdMap<(&'static str, &'static DisallowedPathWithoutReplacement)>,
|
||||
|
||||
@@ -220,11 +220,11 @@ pub struct Cargo {
|
||||
|
||||
impl_lint_pass!(Cargo => [
|
||||
CARGO_COMMON_METADATA,
|
||||
REDUNDANT_FEATURE_NAMES,
|
||||
NEGATIVE_FEATURE_NAMES,
|
||||
MULTIPLE_CRATE_VERSIONS,
|
||||
WILDCARD_DEPENDENCIES,
|
||||
LINT_GROUPS_PRIORITY,
|
||||
MULTIPLE_CRATE_VERSIONS,
|
||||
NEGATIVE_FEATURE_NAMES,
|
||||
REDUNDANT_FEATURE_NAMES,
|
||||
WILDCARD_DEPENDENCIES,
|
||||
]);
|
||||
|
||||
impl Cargo {
|
||||
|
||||
@@ -857,34 +857,34 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
}
|
||||
|
||||
impl_lint_pass!(Casts => [
|
||||
CAST_PRECISION_LOSS,
|
||||
CAST_SIGN_LOSS,
|
||||
CAST_POSSIBLE_TRUNCATION,
|
||||
CAST_POSSIBLE_WRAP,
|
||||
CAST_LOSSLESS,
|
||||
CAST_PTR_ALIGNMENT,
|
||||
CAST_SLICE_DIFFERENT_SIZES,
|
||||
UNNECESSARY_CAST,
|
||||
FN_TO_NUMERIC_CAST_ANY,
|
||||
FN_TO_NUMERIC_CAST,
|
||||
FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
|
||||
CHAR_LIT_AS_U8,
|
||||
PTR_AS_PTR,
|
||||
PTR_CAST_CONSTNESS,
|
||||
CAST_ENUM_TRUNCATION,
|
||||
CAST_ENUM_CONSTRUCTOR,
|
||||
CAST_ABS_TO_UNSIGNED,
|
||||
AS_POINTER_UNDERSCORE,
|
||||
AS_PTR_CAST_MUT,
|
||||
AS_UNDERSCORE,
|
||||
BORROW_AS_PTR,
|
||||
CAST_SLICE_FROM_RAW_PARTS,
|
||||
AS_PTR_CAST_MUT,
|
||||
CAST_ABS_TO_UNSIGNED,
|
||||
CAST_ENUM_CONSTRUCTOR,
|
||||
CAST_ENUM_TRUNCATION,
|
||||
CAST_LOSSLESS,
|
||||
CAST_NAN_TO_INT,
|
||||
ZERO_PTR,
|
||||
REF_AS_PTR,
|
||||
AS_POINTER_UNDERSCORE,
|
||||
MANUAL_DANGLING_PTR,
|
||||
CAST_POSSIBLE_TRUNCATION,
|
||||
CAST_POSSIBLE_WRAP,
|
||||
CAST_PRECISION_LOSS,
|
||||
CAST_PTR_ALIGNMENT,
|
||||
CAST_SIGN_LOSS,
|
||||
CAST_SLICE_DIFFERENT_SIZES,
|
||||
CAST_SLICE_FROM_RAW_PARTS,
|
||||
CHAR_LIT_AS_U8,
|
||||
CONFUSING_METHOD_TO_NUMERIC_CAST,
|
||||
FN_TO_NUMERIC_CAST,
|
||||
FN_TO_NUMERIC_CAST_ANY,
|
||||
FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
|
||||
MANUAL_DANGLING_PTR,
|
||||
NEEDLESS_TYPE_CAST,
|
||||
PTR_AS_PTR,
|
||||
PTR_CAST_CONSTNESS,
|
||||
REF_AS_PTR,
|
||||
UNNECESSARY_CAST,
|
||||
ZERO_PTR,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Casts {
|
||||
|
||||
@@ -259,7 +259,7 @@ fn check_significant_tokens_and_expect_attrs(
|
||||
}
|
||||
}
|
||||
|
||||
impl_lint_pass!(CollapsibleIf => [COLLAPSIBLE_IF, COLLAPSIBLE_ELSE_IF]);
|
||||
impl_lint_pass!(CollapsibleIf => [COLLAPSIBLE_ELSE_IF, COLLAPSIBLE_IF]);
|
||||
|
||||
impl LateLintPass<'_> for CollapsibleIf {
|
||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||
|
||||
@@ -45,7 +45,9 @@
|
||||
complexity,
|
||||
"unit structs can be constructed without calling `default`"
|
||||
}
|
||||
declare_lint_pass!(DefaultConstructedUnitStructs => [DEFAULT_CONSTRUCTED_UNIT_STRUCTS]);
|
||||
declare_lint_pass!(DefaultConstructedUnitStructs => [
|
||||
DEFAULT_CONSTRUCTED_UNIT_STRUCTS,
|
||||
]);
|
||||
|
||||
fn is_alias(ty: hir::Ty<'_>) -> bool {
|
||||
if let hir::TyKind::Path(ref qpath) = ty.kind {
|
||||
|
||||
@@ -144,10 +144,10 @@
|
||||
}
|
||||
|
||||
impl_lint_pass!(Dereferencing<'_> => [
|
||||
EXPLICIT_AUTO_DEREF,
|
||||
EXPLICIT_DEREF_METHODS,
|
||||
NEEDLESS_BORROW,
|
||||
REF_BINDING_TO_REFERENCE,
|
||||
EXPLICIT_AUTO_DEREF,
|
||||
]);
|
||||
|
||||
#[derive(Default)]
|
||||
|
||||
@@ -185,11 +185,11 @@
|
||||
}
|
||||
|
||||
declare_lint_pass!(Derive => [
|
||||
EXPL_IMPL_CLONE_ON_COPY,
|
||||
DERIVED_HASH_WITH_MANUAL_EQ,
|
||||
DERIVE_ORD_XOR_PARTIAL_ORD,
|
||||
DERIVE_PARTIAL_EQ_WITHOUT_EQ,
|
||||
EXPL_IMPL_CLONE_ON_COPY,
|
||||
UNSAFE_DERIVE_DESERIALIZE,
|
||||
DERIVE_PARTIAL_EQ_WITHOUT_EQ
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Derive {
|
||||
|
||||
+11
-11
@@ -719,26 +719,26 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
}
|
||||
|
||||
impl_lint_pass!(Documentation => [
|
||||
DOC_BROKEN_LINK,
|
||||
DOC_COMMENT_DOUBLE_SPACE_LINEBREAKS,
|
||||
DOC_INCLUDE_WITHOUT_CFG,
|
||||
DOC_LAZY_CONTINUATION,
|
||||
DOC_LINK_CODE,
|
||||
DOC_LINK_WITH_QUOTES,
|
||||
DOC_BROKEN_LINK,
|
||||
DOC_MARKDOWN,
|
||||
DOC_NESTED_REFDEFS,
|
||||
MISSING_SAFETY_DOC,
|
||||
DOC_OVERINDENTED_LIST_ITEMS,
|
||||
DOC_PARAGRAPHS_MISSING_PUNCTUATION,
|
||||
DOC_SUSPICIOUS_FOOTNOTES,
|
||||
EMPTY_DOCS,
|
||||
MISSING_ERRORS_DOC,
|
||||
MISSING_PANICS_DOC,
|
||||
MISSING_SAFETY_DOC,
|
||||
NEEDLESS_DOCTEST_MAIN,
|
||||
TEST_ATTR_IN_DOCTEST,
|
||||
UNNECESSARY_SAFETY_DOC,
|
||||
SUSPICIOUS_DOC_COMMENTS,
|
||||
EMPTY_DOCS,
|
||||
DOC_LAZY_CONTINUATION,
|
||||
DOC_OVERINDENTED_LIST_ITEMS,
|
||||
TEST_ATTR_IN_DOCTEST,
|
||||
TOO_LONG_FIRST_DOC_PARAGRAPH,
|
||||
DOC_INCLUDE_WITHOUT_CFG,
|
||||
DOC_COMMENT_DOUBLE_SPACE_LINEBREAKS,
|
||||
DOC_SUSPICIOUS_FOOTNOTES,
|
||||
DOC_PARAGRAPHS_MISSING_PUNCTUATION,
|
||||
UNNECESSARY_SAFETY_DOC,
|
||||
]);
|
||||
|
||||
impl EarlyLintPass for Documentation {
|
||||
|
||||
@@ -75,11 +75,7 @@
|
||||
const FORGET_NON_DROP_SUMMARY: &str = "call to `std::mem::forget` with a value that does not implement `Drop`. \
|
||||
Forgetting such a type is the same as dropping it";
|
||||
|
||||
declare_lint_pass!(DropForgetRef => [
|
||||
DROP_NON_DROP,
|
||||
FORGET_NON_DROP,
|
||||
MEM_FORGET,
|
||||
]);
|
||||
declare_lint_pass!(DropForgetRef => [DROP_NON_DROP, FORGET_NON_DROP, MEM_FORGET]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for DropForgetRef {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
|
||||
@@ -101,8 +101,8 @@ pub struct EmptyLineAfter {
|
||||
}
|
||||
|
||||
impl_lint_pass!(EmptyLineAfter => [
|
||||
EMPTY_LINE_AFTER_OUTER_ATTR,
|
||||
EMPTY_LINE_AFTER_DOC_COMMENTS,
|
||||
EMPTY_LINE_AFTER_OUTER_ATTR,
|
||||
]);
|
||||
|
||||
impl EmptyLineAfter {
|
||||
|
||||
@@ -90,7 +90,10 @@ pub struct EmptyWithBrackets {
|
||||
empty_tuple_enum_variants: FxIndexMap<LocalDefId, Usage>,
|
||||
}
|
||||
|
||||
impl_lint_pass!(EmptyWithBrackets => [EMPTY_STRUCTS_WITH_BRACKETS, EMPTY_ENUM_VARIANTS_WITH_BRACKETS]);
|
||||
impl_lint_pass!(EmptyWithBrackets => [
|
||||
EMPTY_ENUM_VARIANTS_WITH_BRACKETS,
|
||||
EMPTY_STRUCTS_WITH_BRACKETS,
|
||||
]);
|
||||
|
||||
impl LateLintPass<'_> for EmptyWithBrackets {
|
||||
fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
|
||||
|
||||
@@ -63,7 +63,11 @@
|
||||
"disallows usage of the `to_be_bytes` method"
|
||||
}
|
||||
|
||||
declare_lint_pass!(EndianBytes => [HOST_ENDIAN_BYTES, LITTLE_ENDIAN_BYTES, BIG_ENDIAN_BYTES]);
|
||||
declare_lint_pass!(EndianBytes => [
|
||||
BIG_ENDIAN_BYTES,
|
||||
HOST_ENDIAN_BYTES,
|
||||
LITTLE_ENDIAN_BYTES,
|
||||
]);
|
||||
|
||||
const HOST_NAMES: [Symbol; 2] = [sym::from_ne_bytes, sym::to_ne_bytes];
|
||||
const LITTLE_NAMES: [Symbol; 2] = [sym::from_le_bytes, sym::to_le_bytes];
|
||||
|
||||
@@ -66,7 +66,10 @@
|
||||
"redundant closures for method calls"
|
||||
}
|
||||
|
||||
declare_lint_pass!(EtaReduction => [REDUNDANT_CLOSURE, REDUNDANT_CLOSURE_FOR_METHOD_CALLS]);
|
||||
declare_lint_pass!(EtaReduction => [
|
||||
REDUNDANT_CLOSURE,
|
||||
REDUNDANT_CLOSURE_FOR_METHOD_CALLS,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for EtaReduction {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
|
||||
|
||||
@@ -102,7 +102,10 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
impl_lint_pass!(ExcessiveBools => [STRUCT_EXCESSIVE_BOOLS, FN_PARAMS_EXCESSIVE_BOOLS]);
|
||||
impl_lint_pass!(ExcessiveBools => [
|
||||
FN_PARAMS_EXCESSIVE_BOOLS,
|
||||
STRUCT_EXCESSIVE_BOOLS,
|
||||
]);
|
||||
|
||||
fn has_n_bools<'tcx>(iter: impl Iterator<Item = &'tcx Ty<'tcx>>, mut count: u64) -> bool {
|
||||
iter.filter(|ty| is_bool(ty)).any(|_| {
|
||||
|
||||
@@ -47,7 +47,9 @@
|
||||
"checks for usage of a scoped visibility modifier, like `pub(crate)`, on fields"
|
||||
}
|
||||
|
||||
declare_lint_pass!(FieldScopedVisibilityModifiers => [FIELD_SCOPED_VISIBILITY_MODIFIERS]);
|
||||
declare_lint_pass!(FieldScopedVisibilityModifiers => [
|
||||
FIELD_SCOPED_VISIBILITY_MODIFIERS,
|
||||
]);
|
||||
|
||||
impl EarlyLintPass for FieldScopedVisibilityModifiers {
|
||||
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
|
||||
|
||||
@@ -65,9 +65,7 @@ pub struct FloatLiteral {
|
||||
const_literal_digits_threshold: usize,
|
||||
}
|
||||
|
||||
impl_lint_pass!(FloatLiteral => [
|
||||
EXCESSIVE_PRECISION, LOSSY_FLOAT_LITERAL
|
||||
]);
|
||||
impl_lint_pass!(FloatLiteral => [EXCESSIVE_PRECISION, LOSSY_FLOAT_LITERAL]);
|
||||
|
||||
impl FloatLiteral {
|
||||
pub fn new(conf: &'static Conf) -> Self {
|
||||
|
||||
@@ -103,10 +103,7 @@
|
||||
"usage of sub-optimal floating point operations"
|
||||
}
|
||||
|
||||
declare_lint_pass!(FloatingPointArithmetic => [
|
||||
IMPRECISE_FLOPS,
|
||||
SUBOPTIMAL_FLOPS
|
||||
]);
|
||||
declare_lint_pass!(FloatingPointArithmetic => [IMPRECISE_FLOPS, SUBOPTIMAL_FLOPS]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
|
||||
@@ -260,12 +260,12 @@
|
||||
|
||||
impl_lint_pass!(FormatArgs<'_> => [
|
||||
FORMAT_IN_FORMAT_ARGS,
|
||||
POINTER_FORMAT,
|
||||
TO_STRING_IN_FORMAT_ARGS,
|
||||
UNINLINED_FORMAT_ARGS,
|
||||
UNNECESSARY_DEBUG_FORMATTING,
|
||||
UNUSED_FORMAT_SPECS,
|
||||
POINTER_FORMAT,
|
||||
UNNECESSARY_TRAILING_COMMA,
|
||||
UNUSED_FORMAT_SPECS,
|
||||
]);
|
||||
|
||||
#[expect(clippy::struct_field_names)]
|
||||
|
||||
@@ -113,7 +113,7 @@ pub fn new(format_args: FormatArgsStorage) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
impl_lint_pass!(FormatImpl => [RECURSIVE_FORMAT_IMPL, PRINT_IN_FORMAT_IMPL]);
|
||||
impl_lint_pass!(FormatImpl => [PRINT_IN_FORMAT_IMPL, RECURSIVE_FORMAT_IMPL]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for FormatImpl {
|
||||
fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &ImplItem<'_>) {
|
||||
|
||||
@@ -138,11 +138,11 @@
|
||||
}
|
||||
|
||||
declare_lint_pass!(Formatting => [
|
||||
SUSPICIOUS_ASSIGNMENT_FORMATTING,
|
||||
SUSPICIOUS_UNARY_OP_FORMATTING,
|
||||
SUSPICIOUS_ELSE_FORMATTING,
|
||||
POSSIBLE_MISSING_COMMA,
|
||||
POSSIBLE_MISSING_ELSE,
|
||||
POSSIBLE_MISSING_COMMA
|
||||
SUSPICIOUS_ASSIGNMENT_FORMATTING,
|
||||
SUSPICIOUS_ELSE_FORMATTING,
|
||||
SUSPICIOUS_UNARY_OP_FORMATTING,
|
||||
]);
|
||||
|
||||
impl EarlyLintPass for Formatting {
|
||||
|
||||
@@ -516,18 +516,18 @@ pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {
|
||||
}
|
||||
|
||||
impl_lint_pass!(Functions => [
|
||||
DOUBLE_MUST_USE,
|
||||
IMPL_TRAIT_IN_PARAMS,
|
||||
MISNAMED_GETTERS,
|
||||
MUST_USE_CANDIDATE,
|
||||
MUST_USE_UNIT,
|
||||
NOT_UNSAFE_PTR_ARG_DEREF,
|
||||
REF_OPTION,
|
||||
RENAMED_FUNCTION_PARAMS,
|
||||
RESULT_LARGE_ERR,
|
||||
RESULT_UNIT_ERR,
|
||||
TOO_MANY_ARGUMENTS,
|
||||
TOO_MANY_LINES,
|
||||
NOT_UNSAFE_PTR_ARG_DEREF,
|
||||
MUST_USE_UNIT,
|
||||
DOUBLE_MUST_USE,
|
||||
MUST_USE_CANDIDATE,
|
||||
RESULT_UNIT_ERR,
|
||||
RESULT_LARGE_ERR,
|
||||
MISNAMED_GETTERS,
|
||||
IMPL_TRAIT_IN_PARAMS,
|
||||
RENAMED_FUNCTION_PARAMS,
|
||||
REF_OPTION,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Functions {
|
||||
|
||||
@@ -160,10 +160,10 @@ pub fn new(tcx: TyCtxt<'tcx>, conf: &'static Conf) -> Self {
|
||||
}
|
||||
|
||||
impl_lint_pass!(CopyAndPaste<'_> => [
|
||||
BRANCHES_SHARING_CODE,
|
||||
IFS_SAME_COND,
|
||||
SAME_FUNCTIONS_IN_IF_CONDITION,
|
||||
IF_SAME_THEN_ELSE,
|
||||
BRANCHES_SHARING_CODE
|
||||
SAME_FUNCTIONS_IN_IF_CONDITION,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for CopyAndPaste<'tcx> {
|
||||
|
||||
@@ -69,7 +69,9 @@
|
||||
"ensures that the semantics of `Borrow` for `Hash` are satisfied when `Borrow<str>` and `Borrow<[u8]>` are implemented"
|
||||
}
|
||||
|
||||
declare_lint_pass!(ImplHashWithBorrowStrBytes => [IMPL_HASH_BORROW_WITH_STR_AND_BYTES]);
|
||||
declare_lint_pass!(ImplHashWithBorrowStrBytes => [
|
||||
IMPL_HASH_BORROW_WITH_STR_AND_BYTES,
|
||||
]);
|
||||
|
||||
impl LateLintPass<'_> for ImplHashWithBorrowStrBytes {
|
||||
/// We are emitting this lint at the Hash impl of a type that implements all
|
||||
|
||||
@@ -83,7 +83,10 @@ pub struct ImplicitSaturatingSub {
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl_lint_pass!(ImplicitSaturatingSub => [IMPLICIT_SATURATING_SUB, INVERTED_SATURATING_SUB]);
|
||||
impl_lint_pass!(ImplicitSaturatingSub => [
|
||||
IMPLICIT_SATURATING_SUB,
|
||||
INVERTED_SATURATING_SUB,
|
||||
]);
|
||||
|
||||
impl ImplicitSaturatingSub {
|
||||
pub fn new(conf: &'static Conf) -> Self {
|
||||
|
||||
@@ -76,7 +76,9 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
impl_lint_pass!(InconsistentStructConstructor => [INCONSISTENT_STRUCT_CONSTRUCTOR]);
|
||||
impl_lint_pass!(InconsistentStructConstructor => [
|
||||
INCONSISTENT_STRUCT_CONSTRUCTOR,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for InconsistentStructConstructor {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
|
||||
|
||||
@@ -88,7 +88,10 @@
|
||||
"type implements inherent method `to_string()`, which gets shadowed by the implementation of the `Display` trait"
|
||||
}
|
||||
|
||||
declare_lint_pass!(InherentToString => [INHERENT_TO_STRING, INHERENT_TO_STRING_SHADOW_DISPLAY]);
|
||||
declare_lint_pass!(InherentToString => [
|
||||
INHERENT_TO_STRING,
|
||||
INHERENT_TO_STRING_SHADOW_DISPLAY,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for InherentToString {
|
||||
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) {
|
||||
|
||||
@@ -197,9 +197,9 @@ fn is_allowed_prefix(&self, prefix: &str) -> bool {
|
||||
|
||||
impl_lint_pass!(ItemNameRepetitions => [
|
||||
ENUM_VARIANT_NAMES,
|
||||
STRUCT_FIELD_NAMES,
|
||||
MODULE_INCEPTION,
|
||||
MODULE_NAME_REPETITIONS,
|
||||
MODULE_INCEPTION
|
||||
STRUCT_FIELD_NAMES,
|
||||
]);
|
||||
|
||||
#[must_use]
|
||||
|
||||
@@ -105,7 +105,10 @@
|
||||
"implementing `IntoIterator for (&|&mut) Type` without an inherent `iter(_mut)` method"
|
||||
}
|
||||
|
||||
declare_lint_pass!(IterWithoutIntoIter => [ITER_WITHOUT_INTO_ITER, INTO_ITER_WITHOUT_ITER]);
|
||||
declare_lint_pass!(IterWithoutIntoIter => [
|
||||
INTO_ITER_WITHOUT_ITER,
|
||||
ITER_WITHOUT_INTO_ITER,
|
||||
]);
|
||||
|
||||
/// Checks if a given type is nameable in a trait (impl).
|
||||
/// RPIT is stable, but impl Trait in traits is not (yet), so when we have
|
||||
|
||||
@@ -93,7 +93,7 @@ pub struct LenZero {
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl_lint_pass!(LenZero => [LEN_ZERO, COMPARISON_TO_EMPTY]);
|
||||
impl_lint_pass!(LenZero => [COMPARISON_TO_EMPTY, LEN_ZERO]);
|
||||
|
||||
impl LenZero {
|
||||
pub fn new(conf: &'static Conf) -> Self {
|
||||
|
||||
@@ -127,7 +127,12 @@
|
||||
"non-binding `let` without a type annotation"
|
||||
}
|
||||
|
||||
declare_lint_pass!(LetUnderscore => [LET_UNDERSCORE_MUST_USE, LET_UNDERSCORE_LOCK, LET_UNDERSCORE_FUTURE, LET_UNDERSCORE_UNTYPED]);
|
||||
declare_lint_pass!(LetUnderscore => [
|
||||
LET_UNDERSCORE_FUTURE,
|
||||
LET_UNDERSCORE_LOCK,
|
||||
LET_UNDERSCORE_MUST_USE,
|
||||
LET_UNDERSCORE_UNTYPED,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
|
||||
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &LetStmt<'tcx>) {
|
||||
|
||||
@@ -135,9 +135,9 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
}
|
||||
|
||||
impl_lint_pass!(Lifetimes => [
|
||||
NEEDLESS_LIFETIMES,
|
||||
ELIDABLE_LIFETIME_NAMES,
|
||||
EXTRA_UNUSED_LIFETIMES,
|
||||
NEEDLESS_LIFETIMES,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Lifetimes {
|
||||
|
||||
@@ -196,10 +196,10 @@ pub struct LiteralDigitGrouping {
|
||||
}
|
||||
|
||||
impl_lint_pass!(LiteralDigitGrouping => [
|
||||
UNREADABLE_LITERAL,
|
||||
INCONSISTENT_DIGIT_GROUPING,
|
||||
LARGE_DIGIT_GROUPS,
|
||||
MISTYPED_LITERAL_SUFFIXES,
|
||||
UNREADABLE_LITERAL,
|
||||
UNUSUAL_BYTE_GROUPINGS,
|
||||
]);
|
||||
|
||||
|
||||
@@ -36,7 +36,9 @@
|
||||
"Checks if string literals have formatting arguments"
|
||||
}
|
||||
|
||||
declare_lint_pass!(LiteralStringWithFormattingArg => [LITERAL_STRING_WITH_FORMATTING_ARGS]);
|
||||
declare_lint_pass!(LiteralStringWithFormattingArg => [
|
||||
LITERAL_STRING_WITH_FORMATTING_ARGS,
|
||||
]);
|
||||
|
||||
fn emit_lint(cx: &LateContext<'_>, expr: &Expr<'_>, spans: &[(Span, Option<String>)]) {
|
||||
if !spans.is_empty()
|
||||
|
||||
@@ -799,30 +799,30 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
}
|
||||
|
||||
impl_lint_pass!(Loops => [
|
||||
MANUAL_MEMCPY,
|
||||
MANUAL_FLATTEN,
|
||||
NEEDLESS_RANGE_LOOP,
|
||||
EXPLICIT_ITER_LOOP,
|
||||
EXPLICIT_INTO_ITER_LOOP,
|
||||
ITER_NEXT_LOOP,
|
||||
WHILE_LET_LOOP,
|
||||
EXPLICIT_COUNTER_LOOP,
|
||||
CHAR_INDICES_AS_BYTE_INDICES,
|
||||
EMPTY_LOOP,
|
||||
WHILE_LET_ON_ITERATOR,
|
||||
EXPLICIT_COUNTER_LOOP,
|
||||
EXPLICIT_INTO_ITER_LOOP,
|
||||
EXPLICIT_ITER_LOOP,
|
||||
FOR_KV_MAP,
|
||||
NEVER_LOOP,
|
||||
INFINITE_LOOP,
|
||||
ITER_NEXT_LOOP,
|
||||
MANUAL_FIND,
|
||||
MANUAL_FLATTEN,
|
||||
MANUAL_MEMCPY,
|
||||
MANUAL_SLICE_FILL,
|
||||
MANUAL_WHILE_LET_SOME,
|
||||
MISSING_SPIN_LOOP,
|
||||
MUT_RANGE_BOUND,
|
||||
WHILE_IMMUTABLE_CONDITION,
|
||||
WHILE_FLOAT,
|
||||
NEEDLESS_RANGE_LOOP,
|
||||
NEVER_LOOP,
|
||||
SAME_ITEM_PUSH,
|
||||
SINGLE_ELEMENT_LOOP,
|
||||
MISSING_SPIN_LOOP,
|
||||
MANUAL_FIND,
|
||||
MANUAL_WHILE_LET_SOME,
|
||||
UNUSED_ENUMERATE_INDEX,
|
||||
INFINITE_LOOP,
|
||||
MANUAL_SLICE_FILL,
|
||||
CHAR_INDICES_AS_BYTE_INDICES,
|
||||
WHILE_FLOAT,
|
||||
WHILE_IMMUTABLE_CONDITION,
|
||||
WHILE_LET_LOOP,
|
||||
WHILE_LET_ON_ITERATOR,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Loops {
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
style,
|
||||
"use dedicated method to check if a float is finite"
|
||||
}
|
||||
impl_lint_pass!(ManualFloatMethods => [MANUAL_IS_INFINITE, MANUAL_IS_FINITE]);
|
||||
impl_lint_pass!(ManualFloatMethods => [MANUAL_IS_FINITE, MANUAL_IS_INFINITE]);
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum Variant {
|
||||
|
||||
@@ -1021,33 +1021,33 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
}
|
||||
|
||||
impl_lint_pass!(Matches => [
|
||||
SINGLE_MATCH,
|
||||
MATCH_REF_PATS,
|
||||
MATCH_BOOL,
|
||||
SINGLE_MATCH_ELSE,
|
||||
MATCH_OVERLAPPING_ARM,
|
||||
MATCH_WILD_ERR_ARM,
|
||||
MATCH_AS_REF,
|
||||
WILDCARD_ENUM_MATCH_ARM,
|
||||
MATCH_WILDCARD_FOR_SINGLE_VARIANTS,
|
||||
WILDCARD_IN_OR_PATTERNS,
|
||||
MATCH_SINGLE_BINDING,
|
||||
INFALLIBLE_DESTRUCTURING_MATCH,
|
||||
REST_PAT_IN_FULLY_BOUND_STRUCTS,
|
||||
REDUNDANT_PATTERN_MATCHING,
|
||||
MATCH_LIKE_MATCHES_MACRO,
|
||||
MATCH_SAME_ARMS,
|
||||
NEEDLESS_MATCH,
|
||||
COLLAPSIBLE_MATCH,
|
||||
INFALLIBLE_DESTRUCTURING_MATCH,
|
||||
MANUAL_FILTER,
|
||||
MANUAL_MAP,
|
||||
MANUAL_OK_ERR,
|
||||
MANUAL_UNWRAP_OR,
|
||||
MANUAL_UNWRAP_OR_DEFAULT,
|
||||
MATCH_AS_REF,
|
||||
MATCH_BOOL,
|
||||
MATCH_LIKE_MATCHES_MACRO,
|
||||
MATCH_OVERLAPPING_ARM,
|
||||
MATCH_REF_PATS,
|
||||
MATCH_SAME_ARMS,
|
||||
MATCH_SINGLE_BINDING,
|
||||
MATCH_STR_CASE_MISMATCH,
|
||||
SIGNIFICANT_DROP_IN_SCRUTINEE,
|
||||
TRY_ERR,
|
||||
MANUAL_MAP,
|
||||
MANUAL_FILTER,
|
||||
MATCH_WILDCARD_FOR_SINGLE_VARIANTS,
|
||||
MATCH_WILD_ERR_ARM,
|
||||
NEEDLESS_MATCH,
|
||||
REDUNDANT_GUARDS,
|
||||
MANUAL_OK_ERR,
|
||||
REDUNDANT_PATTERN_MATCHING,
|
||||
REST_PAT_IN_FULLY_BOUND_STRUCTS,
|
||||
SIGNIFICANT_DROP_IN_SCRUTINEE,
|
||||
SINGLE_MATCH,
|
||||
SINGLE_MATCH_ELSE,
|
||||
TRY_ERR,
|
||||
WILDCARD_ENUM_MATCH_ARM,
|
||||
WILDCARD_IN_OR_PATTERNS,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Matches {
|
||||
|
||||
@@ -125,8 +125,12 @@
|
||||
"replacing a value of type `T` with `T::default()` instead of using `std::mem::take`"
|
||||
}
|
||||
|
||||
impl_lint_pass!(MemReplace =>
|
||||
[MEM_REPLACE_OPTION_WITH_NONE, MEM_REPLACE_OPTION_WITH_SOME, MEM_REPLACE_WITH_UNINIT, MEM_REPLACE_WITH_DEFAULT]);
|
||||
impl_lint_pass!(MemReplace => [
|
||||
MEM_REPLACE_OPTION_WITH_NONE,
|
||||
MEM_REPLACE_OPTION_WITH_SOME,
|
||||
MEM_REPLACE_WITH_DEFAULT,
|
||||
MEM_REPLACE_WITH_UNINIT,
|
||||
]);
|
||||
|
||||
fn check_replace_option_with_none(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) -> bool {
|
||||
if is_none_expr(cx, src) {
|
||||
|
||||
+124
-124
@@ -4783,159 +4783,159 @@ pub fn new(conf: &'static Conf, format_args: FormatArgsStorage) -> Self {
|
||||
}
|
||||
|
||||
impl_lint_pass!(Methods => [
|
||||
UNWRAP_USED,
|
||||
EXPECT_USED,
|
||||
SHOULD_IMPLEMENT_TRAIT,
|
||||
WRONG_SELF_CONVENTION,
|
||||
OK_EXPECT,
|
||||
UNWRAP_OR_DEFAULT,
|
||||
MAP_UNWRAP_OR,
|
||||
RESULT_MAP_OR_INTO_OPTION,
|
||||
OPTION_MAP_OR_NONE,
|
||||
BIND_INSTEAD_OF_MAP,
|
||||
OR_FUN_CALL,
|
||||
OR_THEN_UNWRAP,
|
||||
EXPECT_FUN_CALL,
|
||||
CHARS_NEXT_CMP,
|
||||
BYTES_COUNT_TO_LEN,
|
||||
BYTES_NTH,
|
||||
CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,
|
||||
CHARS_LAST_CMP,
|
||||
CHARS_NEXT_CMP,
|
||||
CLEAR_WITH_DRAIN,
|
||||
CLONED_INSTEAD_OF_COPIED,
|
||||
CLONE_ON_COPY,
|
||||
CLONE_ON_REF_PTR,
|
||||
COLLAPSIBLE_STR_REPLACE,
|
||||
CONST_IS_EMPTY,
|
||||
ITER_OVEREAGER_CLONED,
|
||||
CLONED_INSTEAD_OF_COPIED,
|
||||
FLAT_MAP_OPTION,
|
||||
INEFFICIENT_TO_STRING,
|
||||
NEW_RET_NO_SELF,
|
||||
SINGLE_CHAR_ADD_STR,
|
||||
SEARCH_IS_SOME,
|
||||
FILTER_NEXT,
|
||||
SKIP_WHILE_NEXT,
|
||||
DOUBLE_ENDED_ITERATOR_LAST,
|
||||
DRAIN_COLLECT,
|
||||
ERR_EXPECT,
|
||||
EXPECT_FUN_CALL,
|
||||
EXPECT_USED,
|
||||
EXTEND_WITH_DRAIN,
|
||||
FILETYPE_IS_FILE,
|
||||
FILTER_MAP_BOOL_THEN,
|
||||
FILTER_MAP_IDENTITY,
|
||||
MAP_IDENTITY,
|
||||
MANUAL_FILTER_MAP,
|
||||
MANUAL_FIND_MAP,
|
||||
OPTION_FILTER_MAP,
|
||||
FILTER_MAP_NEXT,
|
||||
FILTER_NEXT,
|
||||
FLAT_MAP_IDENTITY,
|
||||
MAP_FLATTEN,
|
||||
FLAT_MAP_OPTION,
|
||||
FORMAT_COLLECT,
|
||||
FROM_ITER_INSTEAD_OF_COLLECT,
|
||||
GET_FIRST,
|
||||
GET_LAST_WITH_LEN,
|
||||
GET_UNWRAP,
|
||||
IMPLICIT_CLONE,
|
||||
INEFFICIENT_TO_STRING,
|
||||
INSPECT_FOR_EACH,
|
||||
INTO_ITER_ON_REF,
|
||||
IO_OTHER_ERROR,
|
||||
IP_CONSTANT,
|
||||
IS_DIGIT_ASCII_RADIX,
|
||||
ITERATOR_STEP_BY_ZERO,
|
||||
ITER_NEXT_SLICE,
|
||||
ITER_CLONED_COLLECT,
|
||||
ITER_COUNT,
|
||||
ITER_FILTER_IS_OK,
|
||||
ITER_FILTER_IS_SOME,
|
||||
ITER_KV_MAP,
|
||||
ITER_NEXT_SLICE,
|
||||
ITER_NTH,
|
||||
ITER_NTH_ZERO,
|
||||
BYTES_NTH,
|
||||
ITER_ON_EMPTY_COLLECTIONS,
|
||||
ITER_ON_SINGLE_ITEMS,
|
||||
ITER_OUT_OF_BOUNDS,
|
||||
ITER_OVEREAGER_CLONED,
|
||||
ITER_SKIP_NEXT,
|
||||
GET_UNWRAP,
|
||||
GET_LAST_WITH_LEN,
|
||||
STRING_EXTEND_CHARS,
|
||||
ITER_CLONED_COLLECT,
|
||||
ITER_SKIP_ZERO,
|
||||
ITER_WITH_DRAIN,
|
||||
TYPE_ID_ON_BOX,
|
||||
USELESS_ASREF,
|
||||
UNNECESSARY_FOLD,
|
||||
UNNECESSARY_FILTER_MAP,
|
||||
UNNECESSARY_FIND_MAP,
|
||||
INTO_ITER_ON_REF,
|
||||
SUSPICIOUS_MAP,
|
||||
UNINIT_ASSUMED_INIT,
|
||||
JOIN_ABSOLUTE_PATHS,
|
||||
LINES_FILTER_MAP_OK,
|
||||
MANUAL_CONTAINS,
|
||||
MANUAL_C_STR_LITERALS,
|
||||
MANUAL_FILTER_MAP,
|
||||
MANUAL_FIND_MAP,
|
||||
MANUAL_INSPECT,
|
||||
MANUAL_IS_VARIANT_AND,
|
||||
MANUAL_NEXT_BACK,
|
||||
MANUAL_OK_OR,
|
||||
MANUAL_REPEAT_N,
|
||||
MANUAL_SATURATING_ARITHMETIC,
|
||||
ZST_OFFSET,
|
||||
PTR_OFFSET_BY_LITERAL,
|
||||
PTR_OFFSET_WITH_CAST,
|
||||
FILETYPE_IS_FILE,
|
||||
OPTION_AS_REF_DEREF,
|
||||
UNNECESSARY_LAZY_EVALUATIONS,
|
||||
MAP_COLLECT_RESULT_UNIT,
|
||||
FROM_ITER_INSTEAD_OF_COLLECT,
|
||||
INSPECT_FOR_EACH,
|
||||
IMPLICIT_CLONE,
|
||||
SUSPICIOUS_TO_OWNED,
|
||||
SUSPICIOUS_SPLITN,
|
||||
MANUAL_STR_REPEAT,
|
||||
EXTEND_WITH_DRAIN,
|
||||
MANUAL_SPLIT_ONCE,
|
||||
NEEDLESS_SPLITN,
|
||||
UNNECESSARY_TO_OWNED,
|
||||
UNNECESSARY_JOIN,
|
||||
ERR_EXPECT,
|
||||
MANUAL_STR_REPEAT,
|
||||
MANUAL_TRY_FOLD,
|
||||
MAP_ALL_ANY_IDENTITY,
|
||||
MAP_CLONE,
|
||||
MAP_COLLECT_RESULT_UNIT,
|
||||
MAP_ERR_IGNORE,
|
||||
MAP_FLATTEN,
|
||||
MAP_IDENTITY,
|
||||
MAP_UNWRAP_OR,
|
||||
MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES,
|
||||
MUT_MUTEX_LOCK,
|
||||
NAIVE_BYTECOUNT,
|
||||
NEEDLESS_AS_BYTES,
|
||||
NEEDLESS_CHARACTER_ITERATION,
|
||||
NEEDLESS_COLLECT,
|
||||
NEEDLESS_OPTION_AS_DEREF,
|
||||
IS_DIGIT_ASCII_RADIX,
|
||||
NEEDLESS_OPTION_TAKE,
|
||||
NEEDLESS_SPLITN,
|
||||
NEW_RET_NO_SELF,
|
||||
NONSENSICAL_OPEN_OPTIONS,
|
||||
NO_EFFECT_REPLACE,
|
||||
OBFUSCATED_IF_ELSE,
|
||||
ITER_ON_SINGLE_ITEMS,
|
||||
ITER_ON_EMPTY_COLLECTIONS,
|
||||
NAIVE_BYTECOUNT,
|
||||
BYTES_COUNT_TO_LEN,
|
||||
CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,
|
||||
GET_FIRST,
|
||||
MANUAL_OK_OR,
|
||||
MAP_CLONE,
|
||||
MAP_ERR_IGNORE,
|
||||
MUT_MUTEX_LOCK,
|
||||
NONSENSICAL_OPEN_OPTIONS,
|
||||
SUSPICIOUS_OPEN_OPTIONS,
|
||||
OK_EXPECT,
|
||||
OPTION_AS_REF_CLONED,
|
||||
OPTION_AS_REF_DEREF,
|
||||
OPTION_FILTER_MAP,
|
||||
OPTION_MAP_OR_NONE,
|
||||
OR_FUN_CALL,
|
||||
OR_THEN_UNWRAP,
|
||||
PATH_BUF_PUSH_OVERWRITE,
|
||||
PATH_ENDS_WITH_EXT,
|
||||
PTR_OFFSET_BY_LITERAL,
|
||||
PTR_OFFSET_WITH_CAST,
|
||||
RANGE_ZIP_WITH_LEN,
|
||||
REPEAT_ONCE,
|
||||
STABLE_SORT_PRIMITIVE,
|
||||
UNIT_HASH,
|
||||
READONLY_WRITE_LOCK,
|
||||
READ_LINE_WITHOUT_TRIM,
|
||||
UNNECESSARY_SORT_BY,
|
||||
VEC_RESIZE_TO_ZERO,
|
||||
VERBOSE_FILE_READS,
|
||||
ITER_KV_MAP,
|
||||
REDUNDANT_AS_STR,
|
||||
REDUNDANT_ITER_CLONED,
|
||||
REPEAT_ONCE,
|
||||
RESULT_FILTER_MAP,
|
||||
RESULT_MAP_OR_INTO_OPTION,
|
||||
RETURN_AND_THEN,
|
||||
SEARCH_IS_SOME,
|
||||
SEEK_FROM_CURRENT,
|
||||
SEEK_TO_START_INSTEAD_OF_REWIND,
|
||||
NEEDLESS_COLLECT,
|
||||
SUSPICIOUS_COMMAND_ARG_SPACE,
|
||||
CLEAR_WITH_DRAIN,
|
||||
MANUAL_NEXT_BACK,
|
||||
UNNECESSARY_LITERAL_UNWRAP,
|
||||
DRAIN_COLLECT,
|
||||
MANUAL_TRY_FOLD,
|
||||
FORMAT_COLLECT,
|
||||
STRING_LIT_CHARS_ANY,
|
||||
ITER_SKIP_ZERO,
|
||||
FILTER_MAP_BOOL_THEN,
|
||||
READONLY_WRITE_LOCK,
|
||||
ITER_OUT_OF_BOUNDS,
|
||||
PATH_ENDS_WITH_EXT,
|
||||
REDUNDANT_AS_STR,
|
||||
WAKER_CLONE_WAKE,
|
||||
UNNECESSARY_FALLIBLE_CONVERSIONS,
|
||||
JOIN_ABSOLUTE_PATHS,
|
||||
RESULT_FILTER_MAP,
|
||||
ITER_FILTER_IS_SOME,
|
||||
ITER_FILTER_IS_OK,
|
||||
MANUAL_IS_VARIANT_AND,
|
||||
STR_SPLIT_AT_NEWLINE,
|
||||
OPTION_AS_REF_CLONED,
|
||||
UNNECESSARY_RESULT_MAP_OR_ELSE,
|
||||
MANUAL_C_STR_LITERALS,
|
||||
UNNECESSARY_GET_THEN_CHECK,
|
||||
UNNECESSARY_FIRST_THEN_CHECK,
|
||||
NEEDLESS_CHARACTER_ITERATION,
|
||||
MANUAL_INSPECT,
|
||||
UNNECESSARY_MIN_OR_MAX,
|
||||
NEEDLESS_AS_BYTES,
|
||||
MAP_ALL_ANY_IDENTITY,
|
||||
MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES,
|
||||
UNNECESSARY_MAP_OR,
|
||||
DOUBLE_ENDED_ITERATOR_LAST,
|
||||
USELESS_NONZERO_NEW_UNCHECKED,
|
||||
MANUAL_REPEAT_N,
|
||||
SHOULD_IMPLEMENT_TRAIT,
|
||||
SINGLE_CHAR_ADD_STR,
|
||||
SKIP_WHILE_NEXT,
|
||||
SLICED_STRING_AS_BYTES,
|
||||
RETURN_AND_THEN,
|
||||
UNBUFFERED_BYTES,
|
||||
MANUAL_CONTAINS,
|
||||
IO_OTHER_ERROR,
|
||||
STABLE_SORT_PRIMITIVE,
|
||||
STRING_EXTEND_CHARS,
|
||||
STRING_LIT_CHARS_ANY,
|
||||
STR_SPLIT_AT_NEWLINE,
|
||||
SUSPICIOUS_COMMAND_ARG_SPACE,
|
||||
SUSPICIOUS_MAP,
|
||||
SUSPICIOUS_OPEN_OPTIONS,
|
||||
SUSPICIOUS_SPLITN,
|
||||
SUSPICIOUS_TO_OWNED,
|
||||
SWAP_WITH_TEMPORARY,
|
||||
IP_CONSTANT,
|
||||
REDUNDANT_ITER_CLONED,
|
||||
TYPE_ID_ON_BOX,
|
||||
UNBUFFERED_BYTES,
|
||||
UNINIT_ASSUMED_INIT,
|
||||
UNIT_HASH,
|
||||
UNNECESSARY_FALLIBLE_CONVERSIONS,
|
||||
UNNECESSARY_FILTER_MAP,
|
||||
UNNECESSARY_FIND_MAP,
|
||||
UNNECESSARY_FIRST_THEN_CHECK,
|
||||
UNNECESSARY_FOLD,
|
||||
UNNECESSARY_GET_THEN_CHECK,
|
||||
UNNECESSARY_JOIN,
|
||||
UNNECESSARY_LAZY_EVALUATIONS,
|
||||
UNNECESSARY_LITERAL_UNWRAP,
|
||||
UNNECESSARY_MAP_OR,
|
||||
UNNECESSARY_MIN_OR_MAX,
|
||||
UNNECESSARY_OPTION_MAP_OR_ELSE,
|
||||
LINES_FILTER_MAP_OK,
|
||||
UNNECESSARY_RESULT_MAP_OR_ELSE,
|
||||
UNNECESSARY_SORT_BY,
|
||||
UNNECESSARY_TO_OWNED,
|
||||
UNWRAP_OR_DEFAULT,
|
||||
UNWRAP_USED,
|
||||
USELESS_ASREF,
|
||||
USELESS_NONZERO_NEW_UNCHECKED,
|
||||
VEC_RESIZE_TO_ZERO,
|
||||
VERBOSE_FILE_READS,
|
||||
WAKER_CLONE_WAKE,
|
||||
WRONG_SELF_CONVENTION,
|
||||
ZST_OFFSET,
|
||||
]);
|
||||
|
||||
/// Extracts a method call name, args, and `Span` of the method name.
|
||||
|
||||
@@ -94,9 +94,9 @@
|
||||
}
|
||||
|
||||
declare_lint_pass!(LintPass => [
|
||||
SHORT_CIRCUIT_STATEMENT,
|
||||
USED_UNDERSCORE_BINDING,
|
||||
USED_UNDERSCORE_ITEMS,
|
||||
SHORT_CIRCUIT_STATEMENT,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for LintPass {
|
||||
|
||||
@@ -303,15 +303,15 @@
|
||||
}
|
||||
|
||||
declare_lint_pass!(MiscEarlyLints => [
|
||||
UNNEEDED_FIELD_PATTERN,
|
||||
MIXED_CASE_HEX_LITERALS,
|
||||
UNSEPARATED_LITERAL_SUFFIX,
|
||||
SEPARATED_LITERAL_SUFFIX,
|
||||
ZERO_PREFIXED_LITERAL,
|
||||
BUILTIN_TYPE_SHADOW,
|
||||
REDUNDANT_PATTERN,
|
||||
UNNEEDED_WILDCARD_PATTERN,
|
||||
MIXED_CASE_HEX_LITERALS,
|
||||
REDUNDANT_AT_REST_PATTERN,
|
||||
REDUNDANT_PATTERN,
|
||||
SEPARATED_LITERAL_SUFFIX,
|
||||
UNNEEDED_FIELD_PATTERN,
|
||||
UNNEEDED_WILDCARD_PATTERN,
|
||||
UNSEPARATED_LITERAL_SUFFIX,
|
||||
ZERO_PREFIXED_LITERAL,
|
||||
]);
|
||||
|
||||
impl EarlyLintPass for MiscEarlyLints {
|
||||
|
||||
@@ -79,7 +79,10 @@
|
||||
"whether an expression contains a diverging sub expression"
|
||||
}
|
||||
|
||||
declare_lint_pass!(EvalOrderDependence => [MIXED_READ_WRITE_IN_EXPRESSION, DIVERGING_SUB_EXPRESSION]);
|
||||
declare_lint_pass!(EvalOrderDependence => [
|
||||
DIVERGING_SUB_EXPRESSION,
|
||||
MIXED_READ_WRITE_IN_EXPRESSION,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for EvalOrderDependence {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
|
||||
@@ -72,7 +72,7 @@ pub struct MutableKeyType<'tcx> {
|
||||
interior_mut: InteriorMut<'tcx>,
|
||||
}
|
||||
|
||||
impl_lint_pass!(MutableKeyType<'_> => [ MUTABLE_KEY_TYPE ]);
|
||||
impl_lint_pass!(MutableKeyType<'_> => [MUTABLE_KEY_TYPE]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for MutableKeyType<'tcx> {
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
||||
|
||||
@@ -66,7 +66,9 @@ pub struct NeedlessBorrowsForGenericArgs<'tcx> {
|
||||
// `IntoIterator` for arrays requires Rust 1.53.
|
||||
msrv: Msrv,
|
||||
}
|
||||
impl_lint_pass!(NeedlessBorrowsForGenericArgs<'_> => [NEEDLESS_BORROWS_FOR_GENERIC_ARGS]);
|
||||
impl_lint_pass!(NeedlessBorrowsForGenericArgs<'_> => [
|
||||
NEEDLESS_BORROWS_FOR_GENERIC_ARGS,
|
||||
]);
|
||||
|
||||
impl NeedlessBorrowsForGenericArgs<'_> {
|
||||
pub fn new(conf: &'static Conf) -> Self {
|
||||
|
||||
@@ -38,7 +38,9 @@
|
||||
"needless parenthesis on range literals can be removed"
|
||||
}
|
||||
|
||||
declare_lint_pass!(NeedlessParensOnRangeLiterals => [NEEDLESS_PARENS_ON_RANGE_LITERALS]);
|
||||
declare_lint_pass!(NeedlessParensOnRangeLiterals => [
|
||||
NEEDLESS_PARENS_ON_RANGE_LITERALS,
|
||||
]);
|
||||
|
||||
fn snippet_enclosed_in_parenthesis(snippet: &str) -> bool {
|
||||
snippet.starts_with('(') && snippet.ends_with(')')
|
||||
|
||||
@@ -79,7 +79,11 @@ pub struct NoEffect {
|
||||
local_bindings: Vec<Vec<HirId>>,
|
||||
}
|
||||
|
||||
impl_lint_pass!(NoEffect => [NO_EFFECT, UNNECESSARY_OPERATION, NO_EFFECT_UNDERSCORE_BINDING]);
|
||||
impl_lint_pass!(NoEffect => [
|
||||
NO_EFFECT,
|
||||
NO_EFFECT_UNDERSCORE_BINDING,
|
||||
UNNECESSARY_OPERATION,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for NoEffect {
|
||||
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
|
||||
|
||||
@@ -108,7 +108,10 @@
|
||||
suspicious,
|
||||
"non-canonical implementation of `PartialOrd` on an `Ord` type"
|
||||
}
|
||||
impl_lint_pass!(NonCanonicalImpls => [NON_CANONICAL_CLONE_IMPL, NON_CANONICAL_PARTIAL_ORD_IMPL]);
|
||||
impl_lint_pass!(NonCanonicalImpls => [
|
||||
NON_CANONICAL_CLONE_IMPL,
|
||||
NON_CANONICAL_PARTIAL_ORD_IMPL,
|
||||
]);
|
||||
|
||||
#[expect(
|
||||
clippy::struct_field_names,
|
||||
|
||||
@@ -257,7 +257,10 @@ pub struct NonCopyConst<'tcx> {
|
||||
freeze_tys: FxHashMap<Ty<'tcx>, IsFreeze>,
|
||||
}
|
||||
|
||||
impl_lint_pass!(NonCopyConst<'_> => [DECLARE_INTERIOR_MUTABLE_CONST, BORROW_INTERIOR_MUTABLE_CONST]);
|
||||
impl_lint_pass!(NonCopyConst<'_> => [
|
||||
BORROW_INTERIOR_MUTABLE_CONST,
|
||||
DECLARE_INTERIOR_MUTABLE_CONST,
|
||||
]);
|
||||
|
||||
impl<'tcx> NonCopyConst<'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'tcx>, conf: &'static Conf) -> Self {
|
||||
|
||||
@@ -77,7 +77,11 @@ pub struct NonExpressiveNames {
|
||||
pub single_char_binding_names_threshold: u64,
|
||||
}
|
||||
|
||||
impl_lint_pass!(NonExpressiveNames => [SIMILAR_NAMES, MANY_SINGLE_CHAR_NAMES, JUST_UNDERSCORES_AND_DIGITS]);
|
||||
impl_lint_pass!(NonExpressiveNames => [
|
||||
JUST_UNDERSCORES_AND_DIGITS,
|
||||
MANY_SINGLE_CHAR_NAMES,
|
||||
SIMILAR_NAMES,
|
||||
]);
|
||||
|
||||
impl NonExpressiveNames {
|
||||
pub fn new(conf: &'static Conf) -> Self {
|
||||
|
||||
@@ -164,7 +164,10 @@
|
||||
pedantic,
|
||||
"self receiver only used to recursively call method can be removed"
|
||||
}
|
||||
impl_lint_pass!(OnlyUsedInRecursion => [ONLY_USED_IN_RECURSION, SELF_ONLY_USED_IN_RECURSION]);
|
||||
impl_lint_pass!(OnlyUsedInRecursion => [
|
||||
ONLY_USED_IN_RECURSION,
|
||||
SELF_ONLY_USED_IN_RECURSION,
|
||||
]);
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum FnKind {
|
||||
|
||||
@@ -979,35 +979,35 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
impl_lint_pass!(Operators => [
|
||||
ABSURD_EXTREME_COMPARISONS,
|
||||
ARITHMETIC_SIDE_EFFECTS,
|
||||
FLOAT_ARITHMETIC,
|
||||
ASSIGN_OP_PATTERN,
|
||||
MISREFACTORED_ASSIGN_OP,
|
||||
BAD_BIT_MASK,
|
||||
INEFFECTIVE_BIT_MASK,
|
||||
VERBOSE_BIT_MASK,
|
||||
CMP_OWNED,
|
||||
DECIMAL_BITWISE_OPERANDS,
|
||||
DOUBLE_COMPARISONS,
|
||||
IMPOSSIBLE_COMPARISONS,
|
||||
REDUNDANT_COMPARISONS,
|
||||
DURATION_SUBSEC,
|
||||
EQ_OP,
|
||||
OP_REF,
|
||||
ERASING_OP,
|
||||
FLOAT_EQUALITY_WITHOUT_ABS,
|
||||
IDENTITY_OP,
|
||||
INTEGER_DIVISION,
|
||||
INTEGER_DIVISION_REMAINDER_USED,
|
||||
CMP_OWNED,
|
||||
FLOAT_ARITHMETIC,
|
||||
FLOAT_CMP,
|
||||
FLOAT_CMP_CONST,
|
||||
MODULO_ONE,
|
||||
MODULO_ARITHMETIC,
|
||||
NEEDLESS_BITWISE_BOOL,
|
||||
SELF_ASSIGNMENT,
|
||||
MANUAL_MIDPOINT,
|
||||
MANUAL_IS_MULTIPLE_OF,
|
||||
MANUAL_DIV_CEIL,
|
||||
FLOAT_EQUALITY_WITHOUT_ABS,
|
||||
IDENTITY_OP,
|
||||
IMPOSSIBLE_COMPARISONS,
|
||||
INEFFECTIVE_BIT_MASK,
|
||||
INTEGER_DIVISION,
|
||||
INTEGER_DIVISION_REMAINDER_USED,
|
||||
INVALID_UPCAST_COMPARISONS,
|
||||
DECIMAL_BITWISE_OPERANDS
|
||||
MANUAL_DIV_CEIL,
|
||||
MANUAL_IS_MULTIPLE_OF,
|
||||
MANUAL_MIDPOINT,
|
||||
MISREFACTORED_ASSIGN_OP,
|
||||
MODULO_ARITHMETIC,
|
||||
MODULO_ONE,
|
||||
NEEDLESS_BITWISE_BOOL,
|
||||
OP_REF,
|
||||
REDUNDANT_COMPARISONS,
|
||||
SELF_ASSIGNMENT,
|
||||
VERBOSE_BIT_MASK,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Operators {
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
"functions of type `Result<..>` that contain `panic!()` or assertion"
|
||||
}
|
||||
|
||||
declare_lint_pass!(PanicInResultFn => [PANIC_IN_RESULT_FN]);
|
||||
declare_lint_pass!(PanicInResultFn => [PANIC_IN_RESULT_FN]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for PanicInResultFn {
|
||||
fn check_fn(
|
||||
|
||||
@@ -93,7 +93,7 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
"usage of the `unreachable!` macro"
|
||||
}
|
||||
|
||||
impl_lint_pass!(PanicUnimplemented => [UNIMPLEMENTED, UNREACHABLE, TODO, PANIC]);
|
||||
impl_lint_pass!(PanicUnimplemented => [PANIC, TODO, UNIMPLEMENTED, UNREACHABLE]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
|
||||
@@ -237,7 +237,10 @@ fn check_poly_fn(&self, cx: &LateContext<'_>, def_id: LocalDefId, decl: &FnDecl<
|
||||
}
|
||||
}
|
||||
|
||||
impl_lint_pass!(PassByRefOrValue => [TRIVIALLY_COPY_PASS_BY_REF, LARGE_TYPES_PASSED_BY_VALUE]);
|
||||
impl_lint_pass!(PassByRefOrValue => [
|
||||
LARGE_TYPES_PASSED_BY_VALUE,
|
||||
TRIVIALLY_COPY_PASS_BY_REF,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue {
|
||||
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
|
||||
|
||||
@@ -26,7 +26,9 @@
|
||||
suspicious,
|
||||
"Checks for calls to `std::fs::Permissions.set_readonly` with argument `false`"
|
||||
}
|
||||
declare_lint_pass!(PermissionsSetReadonlyFalse => [PERMISSIONS_SET_READONLY_FALSE]);
|
||||
declare_lint_pass!(PermissionsSetReadonlyFalse => [
|
||||
PERMISSIONS_SET_READONLY_FALSE,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for PermissionsSetReadonlyFalse {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||
|
||||
@@ -135,7 +135,7 @@
|
||||
"use `std::ptr::eq` when comparing raw pointers"
|
||||
}
|
||||
|
||||
declare_lint_pass!(Ptr => [PTR_ARG, CMP_NULL, MUT_FROM_REF, PTR_EQ]);
|
||||
declare_lint_pass!(Ptr => [CMP_NULL, MUT_FROM_REF, PTR_ARG, PTR_EQ]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Ptr {
|
||||
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
|
||||
|
||||
@@ -65,7 +65,7 @@ pub struct QuestionMark {
|
||||
inferred_ret_closure_stack: u16,
|
||||
}
|
||||
|
||||
impl_lint_pass!(QuestionMark => [QUESTION_MARK, MANUAL_LET_ELSE]);
|
||||
impl_lint_pass!(QuestionMark => [MANUAL_LET_ELSE, QUESTION_MARK]);
|
||||
|
||||
impl QuestionMark {
|
||||
pub fn new(conf: &'static Conf) -> Self {
|
||||
|
||||
@@ -175,10 +175,10 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
}
|
||||
|
||||
impl_lint_pass!(Ranges => [
|
||||
RANGE_PLUS_ONE,
|
||||
RANGE_MINUS_ONE,
|
||||
REVERSED_EMPTY_RANGES,
|
||||
MANUAL_RANGE_CONTAINS,
|
||||
RANGE_MINUS_ONE,
|
||||
RANGE_PLUS_ONE,
|
||||
REVERSED_EMPTY_RANGES,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Ranges {
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
"slicing instead of dereferencing"
|
||||
}
|
||||
|
||||
declare_lint_pass!(RedundantSlicing => [REDUNDANT_SLICING, DEREF_BY_SLICING]);
|
||||
declare_lint_pass!(RedundantSlicing => [DEREF_BY_SLICING, REDUNDANT_SLICING]);
|
||||
|
||||
static REDUNDANT_SLICING_LINT: (&Lint, &str) = (REDUNDANT_SLICING, "redundant slicing of the whole range");
|
||||
static DEREF_BY_SLICING_LINT: (&Lint, &str) = (DEREF_BY_SLICING, "slicing when dereferencing would work");
|
||||
|
||||
@@ -119,7 +119,7 @@ pub struct Regex {
|
||||
loop_stack: Vec<(OwnerId, Span)>,
|
||||
}
|
||||
|
||||
impl_lint_pass!(Regex => [INVALID_REGEX, TRIVIAL_REGEX, REGEX_CREATION_IN_LOOPS]);
|
||||
impl_lint_pass!(Regex => [INVALID_REGEX, REGEX_CREATION_IN_LOOPS, TRIVIAL_REGEX]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Regex {
|
||||
fn check_crate(&mut self, cx: &LateContext<'tcx>) {
|
||||
|
||||
@@ -115,7 +115,11 @@
|
||||
"using a return statement like `return Err(expr)?;` where removing it would suffice"
|
||||
}
|
||||
|
||||
declare_lint_pass!(Return => [LET_AND_RETURN, NEEDLESS_RETURN, NEEDLESS_RETURN_WITH_QUESTION_MARK]);
|
||||
declare_lint_pass!(Return => [
|
||||
LET_AND_RETURN,
|
||||
NEEDLESS_RETURN,
|
||||
NEEDLESS_RETURN_WITH_QUESTION_MARK,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Return {
|
||||
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
|
||||
|
||||
@@ -111,7 +111,7 @@ pub(crate) struct Shadow {
|
||||
bindings: Vec<(FxHashMap<Symbol, Vec<ItemLocalId>>, LocalDefId)>,
|
||||
}
|
||||
|
||||
impl_lint_pass!(Shadow => [SHADOW_SAME, SHADOW_REUSE, SHADOW_UNRELATED]);
|
||||
impl_lint_pass!(Shadow => [SHADOW_REUSE, SHADOW_SAME, SHADOW_UNRELATED]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Shadow {
|
||||
fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
|
||||
|
||||
@@ -109,7 +109,11 @@ fn lint_if_finish(&mut self, cx: &LateContext<'_>, krate: Span, lint_point: Lint
|
||||
}
|
||||
}
|
||||
|
||||
impl_lint_pass!(StdReexports => [STD_INSTEAD_OF_CORE, STD_INSTEAD_OF_ALLOC, ALLOC_INSTEAD_OF_CORE]);
|
||||
impl_lint_pass!(StdReexports => [
|
||||
ALLOC_INSTEAD_OF_CORE,
|
||||
STD_INSTEAD_OF_ALLOC,
|
||||
STD_INSTEAD_OF_CORE,
|
||||
]);
|
||||
|
||||
#[derive(Debug)]
|
||||
enum LintPoint {
|
||||
|
||||
@@ -82,7 +82,10 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
impl_lint_pass!(StringPatterns => [MANUAL_PATTERN_CHAR_COMPARISON, SINGLE_CHAR_PATTERN]);
|
||||
impl_lint_pass!(StringPatterns => [
|
||||
MANUAL_PATTERN_CHAR_COMPARISON,
|
||||
SINGLE_CHAR_PATTERN,
|
||||
]);
|
||||
|
||||
const PATTERN_METHODS: [(Symbol, usize); 22] = [
|
||||
(sym::contains, 0),
|
||||
|
||||
@@ -243,7 +243,10 @@ fn is_add(cx: &LateContext<'_>, src: &Expr<'_>, target: &Expr<'_>) -> bool {
|
||||
// Max length a b"foo" string can take
|
||||
const MAX_LENGTH_BYTE_STRING_LIT: usize = 32;
|
||||
|
||||
declare_lint_pass!(StringLitAsBytes => [STRING_LIT_AS_BYTES, STRING_FROM_UTF8_AS_BYTES]);
|
||||
declare_lint_pass!(StringLitAsBytes => [
|
||||
STRING_FROM_UTF8_AS_BYTES,
|
||||
STRING_LIT_AS_BYTES,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
|
||||
|
||||
@@ -64,7 +64,9 @@
|
||||
"groupings of binary operations that look suspiciously like typos"
|
||||
}
|
||||
|
||||
declare_lint_pass!(SuspiciousOperationGroupings => [SUSPICIOUS_OPERATION_GROUPINGS]);
|
||||
declare_lint_pass!(SuspiciousOperationGroupings => [
|
||||
SUSPICIOUS_OPERATION_GROUPINGS,
|
||||
]);
|
||||
|
||||
impl EarlyLintPass for SuspiciousOperationGroupings {
|
||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||
|
||||
@@ -53,7 +53,10 @@
|
||||
"suspicious use of operators in impl of OpAssign trait"
|
||||
}
|
||||
|
||||
declare_lint_pass!(SuspiciousImpl => [SUSPICIOUS_ARITHMETIC_IMPL, SUSPICIOUS_OP_ASSIGN_IMPL]);
|
||||
declare_lint_pass!(SuspiciousImpl => [
|
||||
SUSPICIOUS_ARITHMETIC_IMPL,
|
||||
SUSPICIOUS_OP_ASSIGN_IMPL,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
"`foo = bar; bar = foo` sequence"
|
||||
}
|
||||
|
||||
declare_lint_pass!(Swap => [MANUAL_SWAP, ALMOST_SWAPPED]);
|
||||
declare_lint_pass!(Swap => [ALMOST_SWAPPED, MANUAL_SWAP]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Swap {
|
||||
fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'_>) {
|
||||
|
||||
@@ -83,7 +83,10 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
impl_lint_pass!(UncheckedTimeSubtraction => [MANUAL_INSTANT_ELAPSED, UNCHECKED_TIME_SUBTRACTION]);
|
||||
impl_lint_pass!(UncheckedTimeSubtraction => [
|
||||
MANUAL_INSTANT_ELAPSED,
|
||||
UNCHECKED_TIME_SUBTRACTION,
|
||||
]);
|
||||
|
||||
impl LateLintPass<'_> for UncheckedTimeSubtraction {
|
||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
|
||||
|
||||
@@ -100,7 +100,10 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
impl_lint_pass!(TraitBounds => [TYPE_REPETITION_IN_BOUNDS, TRAIT_DUPLICATION_IN_BOUNDS]);
|
||||
impl_lint_pass!(TraitBounds => [
|
||||
TRAIT_DUPLICATION_IN_BOUNDS,
|
||||
TYPE_REPETITION_IN_BOUNDS,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for TraitBounds {
|
||||
fn check_generics(&mut self, cx: &LateContext<'tcx>, generics: &'tcx Generics<'_>) {
|
||||
|
||||
@@ -474,20 +474,20 @@ pub struct Transmute {
|
||||
}
|
||||
impl_lint_pass!(Transmute => [
|
||||
CROSSPOINTER_TRANSMUTE,
|
||||
TRANSMUTE_PTR_TO_REF,
|
||||
TRANSMUTE_PTR_TO_PTR,
|
||||
USELESS_TRANSMUTE,
|
||||
WRONG_TRANSMUTE,
|
||||
EAGER_TRANSMUTE,
|
||||
MISSING_TRANSMUTE_ANNOTATIONS,
|
||||
TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,
|
||||
TRANSMUTE_BYTES_TO_STR,
|
||||
TRANSMUTE_INT_TO_BOOL,
|
||||
TRANSMUTE_INT_TO_NON_ZERO,
|
||||
UNSOUND_COLLECTION_TRANSMUTE,
|
||||
TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,
|
||||
TRANSMUTE_NULL_TO_FN,
|
||||
TRANSMUTE_PTR_TO_PTR,
|
||||
TRANSMUTE_PTR_TO_REF,
|
||||
TRANSMUTE_UNDEFINED_REPR,
|
||||
TRANSMUTING_NULL,
|
||||
TRANSMUTE_NULL_TO_FN,
|
||||
EAGER_TRANSMUTE,
|
||||
MISSING_TRANSMUTE_ANNOTATIONS,
|
||||
UNSOUND_COLLECTION_TRANSMUTE,
|
||||
USELESS_TRANSMUTE,
|
||||
WRONG_TRANSMUTE,
|
||||
]);
|
||||
impl Transmute {
|
||||
pub fn new(conf: &'static Conf) -> Self {
|
||||
|
||||
@@ -398,16 +398,16 @@ pub struct Types {
|
||||
}
|
||||
|
||||
impl_lint_pass!(Types => [
|
||||
BOX_COLLECTION,
|
||||
VEC_BOX,
|
||||
OPTION_OPTION,
|
||||
LINKEDLIST,
|
||||
BORROWED_BOX,
|
||||
REDUNDANT_ALLOCATION,
|
||||
BOX_COLLECTION,
|
||||
LINKEDLIST,
|
||||
OPTION_OPTION,
|
||||
OWNED_COW,
|
||||
RC_BUFFER,
|
||||
RC_MUTEX,
|
||||
REDUNDANT_ALLOCATION,
|
||||
TYPE_COMPLEXITY,
|
||||
OWNED_COW
|
||||
VEC_BOX,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Types {
|
||||
|
||||
@@ -106,7 +106,10 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
impl_lint_pass!(UndocumentedUnsafeBlocks => [UNDOCUMENTED_UNSAFE_BLOCKS, UNNECESSARY_SAFETY_COMMENT]);
|
||||
impl_lint_pass!(UndocumentedUnsafeBlocks => [
|
||||
UNDOCUMENTED_UNSAFE_BLOCKS,
|
||||
UNNECESSARY_SAFETY_COMMENT,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
|
||||
fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {
|
||||
|
||||
@@ -72,7 +72,11 @@
|
||||
"using a Unicode literal not in NFC normal form (see [Unicode tr15](http://www.unicode.org/reports/tr15/) for further information)"
|
||||
}
|
||||
|
||||
declare_lint_pass!(Unicode => [INVISIBLE_CHARACTERS, NON_ASCII_LITERAL, UNICODE_NOT_NFC]);
|
||||
declare_lint_pass!(Unicode => [
|
||||
INVISIBLE_CHARACTERS,
|
||||
NON_ASCII_LITERAL,
|
||||
UNICODE_NOT_NFC,
|
||||
]);
|
||||
|
||||
impl LateLintPass<'_> for Unicode {
|
||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
|
||||
|
||||
@@ -101,7 +101,7 @@ pub struct UnitTypes {
|
||||
format_args: FormatArgsStorage,
|
||||
}
|
||||
|
||||
impl_lint_pass!(UnitTypes => [LET_UNIT_VALUE, UNIT_CMP, UNIT_ARG]);
|
||||
impl_lint_pass!(UnitTypes => [LET_UNIT_VALUE, UNIT_ARG, UNIT_CMP]);
|
||||
|
||||
impl UnitTypes {
|
||||
pub fn new(format_args: FormatArgsStorage) -> Self {
|
||||
|
||||
@@ -31,7 +31,9 @@
|
||||
complexity,
|
||||
"using `map`/`map_err` on `Option` or `Result` constructors"
|
||||
}
|
||||
declare_lint_pass!(UnnecessaryMapOnConstructor => [UNNECESSARY_MAP_ON_CONSTRUCTOR]);
|
||||
declare_lint_pass!(UnnecessaryMapOnConstructor => [
|
||||
UNNECESSARY_MAP_ON_CONSTRUCTOR,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for UnnecessaryMapOnConstructor {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
|
||||
|
||||
@@ -30,7 +30,9 @@
|
||||
style,
|
||||
"detects cases of references to owned empty strings being passed as an argument to a function expecting `&str`"
|
||||
}
|
||||
declare_lint_pass!(UnnecessaryOwnedEmptyStrings => [UNNECESSARY_OWNED_EMPTY_STRINGS]);
|
||||
declare_lint_pass!(UnnecessaryOwnedEmptyStrings => [
|
||||
UNNECESSARY_OWNED_EMPTY_STRINGS,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for UnnecessaryOwnedEmptyStrings {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
"functions of type `Result<..>` or `Option`<...> that contain `expect()` or `unwrap()`"
|
||||
}
|
||||
|
||||
impl_lint_pass!(UnwrapInResult=> [UNWRAP_IN_RESULT]);
|
||||
impl_lint_pass!(UnwrapInResult => [UNWRAP_IN_RESULT]);
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||
enum OptionOrResult {
|
||||
|
||||
@@ -74,7 +74,11 @@
|
||||
restriction,
|
||||
"disallows usage of `pub(in <loc>)` with `in`"
|
||||
}
|
||||
declare_lint_pass!(Visibility => [NEEDLESS_PUB_SELF, PUB_WITH_SHORTHAND, PUB_WITHOUT_SHORTHAND]);
|
||||
declare_lint_pass!(Visibility => [
|
||||
NEEDLESS_PUB_SELF,
|
||||
PUB_WITHOUT_SHORTHAND,
|
||||
PUB_WITH_SHORTHAND,
|
||||
]);
|
||||
|
||||
impl EarlyLintPass for Visibility {
|
||||
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
|
||||
|
||||
@@ -257,15 +257,15 @@ fn in_debug_impl(&self) -> bool {
|
||||
}
|
||||
|
||||
impl_lint_pass!(Write => [
|
||||
PRINT_WITH_NEWLINE,
|
||||
PRINTLN_EMPTY_STRING,
|
||||
PRINT_STDOUT,
|
||||
PRINT_STDERR,
|
||||
USE_DEBUG,
|
||||
PRINT_LITERAL,
|
||||
WRITE_WITH_NEWLINE,
|
||||
PRINT_STDERR,
|
||||
PRINT_STDOUT,
|
||||
PRINT_WITH_NEWLINE,
|
||||
USE_DEBUG,
|
||||
WRITELN_EMPTY_STRING,
|
||||
WRITE_LITERAL,
|
||||
WRITE_WITH_NEWLINE,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Write {
|
||||
|
||||
Reference in New Issue
Block a user