clippy_dev: Parse and format lint pass macros.

This commit is contained in:
Jason Newcomb
2025-10-24 21:24:35 -04:00
parent 9798fafcb7
commit 1f2be4e71b
88 changed files with 962 additions and 564 deletions
+5 -6
View File
@@ -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
View File
@@ -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
View File
@@ -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
}
}
+1 -1
View File
@@ -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;
+3 -4
View File
@@ -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
View File
@@ -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(),
});
}
},
_ => {},
}
}
}
+82 -4
View File
@@ -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.
///
+24
View File
@@ -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 }
}
+7 -10
View File
@@ -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 {
+5 -1
View File
@@ -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)>,
+4 -4
View File
@@ -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 {
+23 -23
View File
@@ -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 {
+1 -1
View File
@@ -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 {
+1 -1
View File
@@ -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)]
+2 -2
View File
@@ -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
View File
@@ -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 {
+1 -5
View File
@@ -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<'_>) {
+1 -1
View File
@@ -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 {
+4 -1
View File
@@ -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<'_>) {
+5 -1
View File
@@ -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];
+4 -1
View File
@@ -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>) {
+4 -1
View File
@@ -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) {
+1 -3
View File
@@ -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<'_>) {
+2 -2
View File
@@ -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)]
+1 -1
View File
@@ -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<'_>) {
+4 -4
View File
@@ -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 {
+10 -10
View File
@@ -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 {
+2 -2
View File
@@ -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
+4 -1
View File
@@ -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<'_>) {
+4 -1
View File
@@ -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<'_>) {
+2 -2
View File
@@ -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]
+4 -1
View File
@@ -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
+1 -1
View File
@@ -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 {
+6 -1
View File
@@ -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>) {
+1 -1
View File
@@ -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 {
+1 -1
View File
@@ -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()
+18 -18
View File
@@ -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 {
+1 -1
View File
@@ -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 {
+22 -22
View File
@@ -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 {
+6 -2
View File
@@ -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
View File
@@ -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.
+1 -1
View File
@@ -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 {
+7 -7
View File
@@ -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<'_>) {
+1 -1
View File
@@ -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(')')
+5 -1
View File
@@ -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<'_>) {
+4 -1
View File
@@ -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,
+4 -1
View File
@@ -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 {
+5 -1
View File
@@ -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 {
+4 -1
View File
@@ -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 {
+20 -20
View File
@@ -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 {
+1 -1
View File
@@ -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(
+1 -1
View File
@@ -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<'_>) {
+4 -1
View File
@@ -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>) {
+1 -1
View File
@@ -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<'_>) {
+1 -1
View File
@@ -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 {
+3 -3
View File
@@ -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 {
+1 -1
View File
@@ -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");
+1 -1
View File
@@ -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>) {
+5 -1
View File
@@ -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<'_>) {
+1 -1
View File
@@ -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<'_>) {
+5 -1
View File
@@ -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 {
+4 -1
View File
@@ -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),
+4 -1
View File
@@ -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) {
+4 -1
View File
@@ -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<'_>) {
+1 -1
View File
@@ -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<'_>) {
+4 -1
View File
@@ -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<'_>) {
+4 -1
View File
@@ -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<'_>) {
+9 -9
View File
@@ -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 {
+6 -6
View File
@@ -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>) {
+5 -1
View File
@@ -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<'_>) {
+1 -1
View File
@@ -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>) {
+1 -1
View File
@@ -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 {
+5 -1
View File
@@ -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) {
+5 -5
View File
@@ -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 {