mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 23:24:24 +00:00
Auto merge of #81993 - flip1995:clippyup, r=Manishearth
Update Clippy Biweekly Clippy update r? `@Manishearth`
This commit is contained in:
commit
a149f61244
80 changed files with 1796 additions and 604 deletions
|
@ -1877,6 +1877,7 @@ Released 2018-09-13
|
|||
[`box_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#box_vec
|
||||
[`boxed_local`]: https://rust-lang.github.io/rust-clippy/master/index.html#boxed_local
|
||||
[`builtin_type_shadow`]: https://rust-lang.github.io/rust-clippy/master/index.html#builtin_type_shadow
|
||||
[`bytes_nth`]: https://rust-lang.github.io/rust-clippy/master/index.html#bytes_nth
|
||||
[`cargo_common_metadata`]: https://rust-lang.github.io/rust-clippy/master/index.html#cargo_common_metadata
|
||||
[`case_sensitive_file_extension_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#case_sensitive_file_extension_comparisons
|
||||
[`cast_lossless`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_lossless
|
||||
|
@ -1955,6 +1956,7 @@ Released 2018-09-13
|
|||
[`field_reassign_with_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#field_reassign_with_default
|
||||
[`filetype_is_file`]: https://rust-lang.github.io/rust-clippy/master/index.html#filetype_is_file
|
||||
[`filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_map
|
||||
[`filter_map_identity`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_identity
|
||||
[`filter_map_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_next
|
||||
[`filter_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_next
|
||||
[`find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#find_map
|
||||
|
@ -2039,6 +2041,7 @@ Released 2018-09-13
|
|||
[`manual_async_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_async_fn
|
||||
[`manual_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_filter_map
|
||||
[`manual_find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_find_map
|
||||
[`manual_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_flatten
|
||||
[`manual_memcpy`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_memcpy
|
||||
[`manual_non_exhaustive`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive
|
||||
[`manual_ok_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ok_or
|
||||
|
@ -2184,6 +2187,7 @@ Released 2018-09-13
|
|||
[`same_item_push`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push
|
||||
[`search_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#search_is_some
|
||||
[`self_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_assignment
|
||||
[`semicolon_if_nothing_returned`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
|
||||
[`serde_api_misuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#serde_api_misuse
|
||||
[`shadow_reuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_reuse
|
||||
[`shadow_same`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_same
|
||||
|
|
|
@ -9,6 +9,7 @@ edition = "2018"
|
|||
bytecount = "0.6"
|
||||
clap = "2.33"
|
||||
flate2 = { version = "1.0.19", optional = true }
|
||||
fs_extra = { version = "1.2.0", optional = true }
|
||||
itertools = "0.9"
|
||||
opener = "0.4"
|
||||
regex = "1"
|
||||
|
@ -21,5 +22,5 @@ ureq = { version = "2.0.0-rc3", optional = true }
|
|||
walkdir = "2"
|
||||
|
||||
[features]
|
||||
lintcheck = ["flate2", "serde_json", "tar", "toml", "ureq", "serde"]
|
||||
lintcheck = ["flate2", "serde_json", "tar", "toml", "ureq", "serde", "fs_extra"]
|
||||
deny-warnings = []
|
||||
|
|
28
clippy_dev/README.md
Normal file
28
clippy_dev/README.md
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Clippy Dev Tool
|
||||
|
||||
The Clippy Dev Tool is a tool to ease Clippy development, similar to `rustc`s `x.py`.
|
||||
|
||||
Functionalities (incomplete):
|
||||
|
||||
## `lintcheck`
|
||||
Runs clippy on a fixed set of crates read from `clippy_dev/lintcheck_crates.toml`
|
||||
and saves logs of the lint warnings into the repo.
|
||||
We can then check the diff and spot new or disappearing warnings.
|
||||
|
||||
From the repo root, run:
|
||||
````
|
||||
cargo run --target-dir clippy_dev/target --package clippy_dev \
|
||||
--bin clippy_dev --manifest-path clippy_dev/Cargo.toml --features lintcheck -- lintcheck
|
||||
````
|
||||
or
|
||||
````
|
||||
cargo dev-lintcheck
|
||||
````
|
||||
|
||||
By default the logs will be saved into `lintcheck-logs/lintcheck_crates_logs.txt`.
|
||||
|
||||
You can set a custom sources.toml by adding `--crates-toml custom.toml`
|
||||
where `custom.toml` must be a relative path from the repo root.
|
||||
|
||||
The results will then be saved to `lintcheck-logs/custom_logs.toml`.
|
||||
|
|
@ -1,20 +1,23 @@
|
|||
[crates]
|
||||
# some of these are from cargotest
|
||||
cargo = ['0.49.0']
|
||||
iron = ['0.6.1']
|
||||
ripgrep = ['12.1.1']
|
||||
xsv = ['0.13.0']
|
||||
#tokei = ['12.0.4']
|
||||
rayon = ['1.5.0']
|
||||
serde = ['1.0.118']
|
||||
cargo = {name = "cargo", versions = ['0.49.0']}
|
||||
iron = {name = "iron", versions = ['0.6.1']}
|
||||
ripgrep = {name = "ripgrep", versions = ['12.1.1']}
|
||||
xsv = {name = "xsv", versions = ['0.13.0']}
|
||||
# commented out because of 173K clippy::match_same_arms msgs in language_type.rs
|
||||
#tokei = { name = "tokei", versions = ['12.0.4']}
|
||||
rayon = {name = "rayon", versions = ['1.5.0']}
|
||||
serde = {name = "serde", versions = ['1.0.118']}
|
||||
# top 10 crates.io dls
|
||||
bitflags = ['1.2.1']
|
||||
libc = ['0.2.81']
|
||||
log = ['0.4.11']
|
||||
proc-macro2 = ['1.0.24']
|
||||
quote = ['1.0.7']
|
||||
rand = ['0.7.3']
|
||||
rand_core = ['0.6.0']
|
||||
regex = ['1.3.2']
|
||||
syn = ['1.0.54']
|
||||
unicode-xid = ['0.2.1']
|
||||
bitflags = {name = "bitflags", versions = ['1.2.1']}
|
||||
# crash = {name = "clippy_crash", path = "/tmp/clippy_crash"}
|
||||
libc = {name = "libc", versions = ['0.2.81']}
|
||||
log = {name = "log", versions = ['0.4.11']}
|
||||
proc-macro2 = {name = "proc-macro2", versions = ['1.0.24']}
|
||||
puffin = {name = "puffin", git_url = "https://github.com/EmbarkStudios/puffin", git_hash = "02dd4a3"}
|
||||
quote = {name = "quote", versions = ['1.0.7']}
|
||||
rand = {name = "rand", versions = ['0.7.3']}
|
||||
rand_core = {name = "rand_core", versions = ['0.6.0']}
|
||||
regex = {name = "regex", versions = ['1.3.2']}
|
||||
syn = {name = "syn", versions = ['1.0.54']}
|
||||
unicode-xid = {name = "unicode-xid", versions = ['0.2.1']}
|
||||
|
|
|
@ -20,24 +20,31 @@ use serde_json::Value;
|
|||
// use this to store the crates when interacting with the crates.toml file
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct CrateList {
|
||||
crates: HashMap<String, Vec<String>>,
|
||||
crates: HashMap<String, TomlCrate>,
|
||||
}
|
||||
|
||||
// crate data we stored in the toml, can have multiple versions per crate
|
||||
// A single TomlCrate is laster mapped to several CrateSources in that case
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct TomlCrate {
|
||||
name: String,
|
||||
versions: Vec<String>,
|
||||
versions: Option<Vec<String>>,
|
||||
git_url: Option<String>,
|
||||
git_hash: Option<String>,
|
||||
path: Option<String>,
|
||||
}
|
||||
|
||||
// represents an archive we download from crates.io
|
||||
// represents an archive we download from crates.io, or a git repo, or a local repo
|
||||
#[derive(Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
|
||||
struct CrateSource {
|
||||
name: String,
|
||||
version: String,
|
||||
enum CrateSource {
|
||||
CratesIo { name: String, version: String },
|
||||
Git { name: String, url: String, commit: String },
|
||||
Path { name: String, path: PathBuf },
|
||||
}
|
||||
|
||||
// represents the extracted sourcecode of a crate
|
||||
// we actually don't need to special-case git repos here because it does not matter for clippy, yay!
|
||||
// (clippy only needs a simple path)
|
||||
#[derive(Debug)]
|
||||
struct Crate {
|
||||
version: String,
|
||||
|
@ -55,6 +62,7 @@ struct ClippyWarning {
|
|||
column: String,
|
||||
linttype: String,
|
||||
message: String,
|
||||
ice: bool,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ClippyWarning {
|
||||
|
@ -69,40 +77,102 @@ impl std::fmt::Display for ClippyWarning {
|
|||
|
||||
impl CrateSource {
|
||||
fn download_and_extract(&self) -> Crate {
|
||||
let extract_dir = PathBuf::from("target/lintcheck/crates");
|
||||
let krate_download_dir = PathBuf::from("target/lintcheck/downloads");
|
||||
match self {
|
||||
CrateSource::CratesIo { name, version } => {
|
||||
let extract_dir = PathBuf::from("target/lintcheck/crates");
|
||||
let krate_download_dir = PathBuf::from("target/lintcheck/downloads");
|
||||
|
||||
// url to download the crate from crates.io
|
||||
let url = format!(
|
||||
"https://crates.io/api/v1/crates/{}/{}/download",
|
||||
self.name, self.version
|
||||
);
|
||||
println!("Downloading and extracting {} {} from {}", self.name, self.version, url);
|
||||
let _ = std::fs::create_dir("target/lintcheck/");
|
||||
let _ = std::fs::create_dir(&krate_download_dir);
|
||||
let _ = std::fs::create_dir(&extract_dir);
|
||||
// url to download the crate from crates.io
|
||||
let url = format!("https://crates.io/api/v1/crates/{}/{}/download", name, version);
|
||||
println!("Downloading and extracting {} {} from {}", name, version, url);
|
||||
let _ = std::fs::create_dir("target/lintcheck/");
|
||||
let _ = std::fs::create_dir(&krate_download_dir);
|
||||
let _ = std::fs::create_dir(&extract_dir);
|
||||
|
||||
let krate_file_path = krate_download_dir.join(format!("{}-{}.crate.tar.gz", &self.name, &self.version));
|
||||
// don't download/extract if we already have done so
|
||||
if !krate_file_path.is_file() {
|
||||
// create a file path to download and write the crate data into
|
||||
let mut krate_dest = std::fs::File::create(&krate_file_path).unwrap();
|
||||
let mut krate_req = ureq::get(&url).call().unwrap().into_reader();
|
||||
// copy the crate into the file
|
||||
std::io::copy(&mut krate_req, &mut krate_dest).unwrap();
|
||||
let krate_file_path = krate_download_dir.join(format!("{}-{}.crate.tar.gz", name, version));
|
||||
// don't download/extract if we already have done so
|
||||
if !krate_file_path.is_file() {
|
||||
// create a file path to download and write the crate data into
|
||||
let mut krate_dest = std::fs::File::create(&krate_file_path).unwrap();
|
||||
let mut krate_req = ureq::get(&url).call().unwrap().into_reader();
|
||||
// copy the crate into the file
|
||||
std::io::copy(&mut krate_req, &mut krate_dest).unwrap();
|
||||
|
||||
// unzip the tarball
|
||||
let ungz_tar = flate2::read::GzDecoder::new(std::fs::File::open(&krate_file_path).unwrap());
|
||||
// extract the tar archive
|
||||
let mut archive = tar::Archive::new(ungz_tar);
|
||||
archive.unpack(&extract_dir).expect("Failed to extract!");
|
||||
}
|
||||
// crate is extracted, return a new Krate object which contains the path to the extracted
|
||||
// sources that clippy can check
|
||||
Crate {
|
||||
version: self.version.clone(),
|
||||
name: self.name.clone(),
|
||||
path: extract_dir.join(format!("{}-{}/", self.name, self.version)),
|
||||
// unzip the tarball
|
||||
let ungz_tar = flate2::read::GzDecoder::new(std::fs::File::open(&krate_file_path).unwrap());
|
||||
// extract the tar archive
|
||||
let mut archive = tar::Archive::new(ungz_tar);
|
||||
archive.unpack(&extract_dir).expect("Failed to extract!");
|
||||
}
|
||||
// crate is extracted, return a new Krate object which contains the path to the extracted
|
||||
// sources that clippy can check
|
||||
Crate {
|
||||
version: version.clone(),
|
||||
name: name.clone(),
|
||||
path: extract_dir.join(format!("{}-{}/", name, version)),
|
||||
}
|
||||
},
|
||||
CrateSource::Git { name, url, commit } => {
|
||||
let repo_path = {
|
||||
let mut repo_path = PathBuf::from("target/lintcheck/crates");
|
||||
// add a -git suffix in case we have the same crate from crates.io and a git repo
|
||||
repo_path.push(format!("{}-git", name));
|
||||
repo_path
|
||||
};
|
||||
// clone the repo if we have not done so
|
||||
if !repo_path.is_dir() {
|
||||
println!("Cloning {} and checking out {}", url, commit);
|
||||
Command::new("git")
|
||||
.arg("clone")
|
||||
.arg(url)
|
||||
.arg(&repo_path)
|
||||
.output()
|
||||
.expect("Failed to clone git repo!");
|
||||
}
|
||||
// check out the commit/branch/whatever
|
||||
Command::new("git")
|
||||
.arg("checkout")
|
||||
.arg(commit)
|
||||
.output()
|
||||
.expect("Failed to check out commit");
|
||||
|
||||
Crate {
|
||||
version: commit.clone(),
|
||||
name: name.clone(),
|
||||
path: repo_path,
|
||||
}
|
||||
},
|
||||
CrateSource::Path { name, path } => {
|
||||
use fs_extra::dir;
|
||||
|
||||
// simply copy the entire directory into our target dir
|
||||
let copy_dest = PathBuf::from("target/lintcheck/crates/");
|
||||
|
||||
// the source path of the crate we copied, ${copy_dest}/crate_name
|
||||
let crate_root = copy_dest.join(name); // .../crates/local_crate
|
||||
|
||||
if !crate_root.exists() {
|
||||
println!("Copying {} to {}", path.display(), copy_dest.display());
|
||||
|
||||
dir::copy(path, ©_dest, &dir::CopyOptions::new()).expect(&format!(
|
||||
"Failed to copy from {}, to {}",
|
||||
path.display(),
|
||||
crate_root.display()
|
||||
));
|
||||
} else {
|
||||
println!(
|
||||
"Not copying {} to {}, destination already exists",
|
||||
path.display(),
|
||||
crate_root.display()
|
||||
);
|
||||
}
|
||||
|
||||
Crate {
|
||||
version: String::from("local"),
|
||||
name: name.clone(),
|
||||
path: crate_root,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,7 +184,7 @@ impl Crate {
|
|||
|
||||
let shared_target_dir = clippy_project_root().join("target/lintcheck/shared_target_dir/");
|
||||
|
||||
let all_output = std::process::Command::new(cargo_clippy_path)
|
||||
let all_output = std::process::Command::new(&cargo_clippy_path)
|
||||
.env("CARGO_TARGET_DIR", shared_target_dir)
|
||||
// lint warnings will look like this:
|
||||
// src/cargo/ops/cargo_compile.rs:127:35: warning: usage of `FromIterator::from_iter`
|
||||
|
@ -128,14 +198,20 @@ impl Crate {
|
|||
])
|
||||
.current_dir(&self.path)
|
||||
.output()
|
||||
.unwrap();
|
||||
.unwrap_or_else(|error| {
|
||||
panic!(
|
||||
"Encountered error:\n{:?}\ncargo_clippy_path: {}\ncrate path:{}\n",
|
||||
error,
|
||||
&cargo_clippy_path.display(),
|
||||
&self.path.display()
|
||||
);
|
||||
});
|
||||
let stdout = String::from_utf8_lossy(&all_output.stdout);
|
||||
let output_lines = stdout.lines();
|
||||
//dbg!(&output_lines);
|
||||
let warnings: Vec<ClippyWarning> = output_lines
|
||||
.into_iter()
|
||||
// get all clippy warnings
|
||||
.filter(|line| line.contains("clippy::"))
|
||||
// get all clippy warnings and ICEs
|
||||
.filter(|line| line.contains("clippy::") || line.contains("internal compiler error: "))
|
||||
.map(|json_msg| parse_json_message(json_msg, &self))
|
||||
.collect();
|
||||
warnings
|
||||
|
@ -150,8 +226,10 @@ fn build_clippy() {
|
|||
}
|
||||
|
||||
// get a list of CrateSources we want to check from a "lintcheck_crates.toml" file.
|
||||
fn read_crates() -> Vec<CrateSource> {
|
||||
let toml_path = PathBuf::from("clippy_dev/lintcheck_crates.toml");
|
||||
fn read_crates(toml_path: Option<&str>) -> (String, Vec<CrateSource>) {
|
||||
let toml_path = PathBuf::from(toml_path.unwrap_or("clippy_dev/lintcheck_crates.toml"));
|
||||
// save it so that we can use the name of the sources.toml as name for the logfile later.
|
||||
let toml_filename = toml_path.file_stem().unwrap().to_str().unwrap().to_string();
|
||||
let toml_content: String =
|
||||
std::fs::read_to_string(&toml_path).unwrap_or_else(|_| panic!("Failed to read {}", toml_path.display()));
|
||||
let crate_list: CrateList =
|
||||
|
@ -160,21 +238,52 @@ fn read_crates() -> Vec<CrateSource> {
|
|||
let tomlcrates: Vec<TomlCrate> = crate_list
|
||||
.crates
|
||||
.into_iter()
|
||||
.map(|(name, versions)| TomlCrate { name, versions })
|
||||
.map(|(_cratename, tomlcrate)| tomlcrate)
|
||||
.collect();
|
||||
|
||||
// flatten TomlCrates into CrateSources (one TomlCrates may represent several versions of a crate =>
|
||||
// multiple Cratesources)
|
||||
let mut crate_sources = Vec::new();
|
||||
tomlcrates.into_iter().for_each(|tk| {
|
||||
tk.versions.iter().for_each(|ver| {
|
||||
crate_sources.push(CrateSource {
|
||||
if let Some(ref path) = tk.path {
|
||||
crate_sources.push(CrateSource::Path {
|
||||
name: tk.name.clone(),
|
||||
version: ver.to_string(),
|
||||
path: PathBuf::from(path),
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// if we have multiple versions, save each one
|
||||
if let Some(ref versions) = tk.versions {
|
||||
versions.iter().for_each(|ver| {
|
||||
crate_sources.push(CrateSource::CratesIo {
|
||||
name: tk.name.clone(),
|
||||
version: ver.to_string(),
|
||||
});
|
||||
})
|
||||
}
|
||||
// otherwise, we should have a git source
|
||||
if tk.git_url.is_some() && tk.git_hash.is_some() {
|
||||
crate_sources.push(CrateSource::Git {
|
||||
name: tk.name.clone(),
|
||||
url: tk.git_url.clone().unwrap(),
|
||||
commit: tk.git_hash.clone().unwrap(),
|
||||
});
|
||||
}
|
||||
// if we have a version as well as a git data OR only one git data, something is funky
|
||||
if tk.versions.is_some() && (tk.git_url.is_some() || tk.git_hash.is_some())
|
||||
|| tk.git_hash.is_some() != tk.git_url.is_some()
|
||||
{
|
||||
eprintln!("tomlkrate: {:?}", tk);
|
||||
if tk.git_hash.is_some() != tk.git_url.is_some() {
|
||||
panic!("Error: Encountered TomlCrate with only one of git_hash and git_url!");
|
||||
}
|
||||
if tk.path.is_some() && (tk.git_hash.is_some() || tk.versions.is_some()) {
|
||||
panic!("Error: TomlCrate can only have one of 'git_.*', 'version' or 'path' fields");
|
||||
}
|
||||
unreachable!("Failed to translate TomlCrate into CrateSource!");
|
||||
}
|
||||
});
|
||||
crate_sources
|
||||
(toml_filename, crate_sources)
|
||||
}
|
||||
|
||||
// extract interesting data from a json lint message
|
||||
|
@ -198,6 +307,7 @@ fn parse_json_message(json_message: &str, krate: &Crate) -> ClippyWarning {
|
|||
.into(),
|
||||
linttype: jmsg["message"]["code"]["code"].to_string().trim_matches('"').into(),
|
||||
message: jmsg["message"]["message"].to_string().trim_matches('"').into(),
|
||||
ice: json_message.contains("internal compiler error: "),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,11 +335,18 @@ pub fn run(clap_config: &ArgMatches) {
|
|||
// download and extract the crates, then run clippy on them and collect clippys warnings
|
||||
// flatten into one big list of warnings
|
||||
|
||||
let crates = read_crates();
|
||||
let (filename, crates) = read_crates(clap_config.value_of("crates-toml"));
|
||||
|
||||
let clippy_warnings: Vec<ClippyWarning> = if let Some(only_one_crate) = clap_config.value_of("only") {
|
||||
// if we don't have the specified crated in the .toml, throw an error
|
||||
if !crates.iter().any(|krate| krate.name == only_one_crate) {
|
||||
// if we don't have the specified crate in the .toml, throw an error
|
||||
if !crates.iter().any(|krate| {
|
||||
let name = match krate {
|
||||
CrateSource::CratesIo { name, .. } => name,
|
||||
CrateSource::Git { name, .. } => name,
|
||||
CrateSource::Path { name, .. } => name,
|
||||
};
|
||||
name == only_one_crate
|
||||
}) {
|
||||
eprintln!(
|
||||
"ERROR: could not find crate '{}' in clippy_dev/lintcheck_crates.toml",
|
||||
only_one_crate
|
||||
|
@ -257,6 +374,13 @@ pub fn run(clap_config: &ArgMatches) {
|
|||
|
||||
// generate some stats:
|
||||
|
||||
// grab crashes/ICEs, save the crate name and the ice message
|
||||
let ices: Vec<(&String, &String)> = clippy_warnings
|
||||
.iter()
|
||||
.filter(|warning| warning.ice)
|
||||
.map(|w| (&w.crate_name, &w.message))
|
||||
.collect();
|
||||
|
||||
// count lint type occurrences
|
||||
let mut counter: HashMap<&String, usize> = HashMap::new();
|
||||
clippy_warnings
|
||||
|
@ -282,5 +406,10 @@ pub fn run(clap_config: &ArgMatches) {
|
|||
// save the text into lintcheck-logs/logs.txt
|
||||
let mut text = clippy_ver; // clippy version number on top
|
||||
text.push_str(&format!("\n{}", all_msgs.join("")));
|
||||
write("lintcheck-logs/logs.txt", text).unwrap();
|
||||
text.push_str("ICEs:\n");
|
||||
ices.iter()
|
||||
.for_each(|(cratename, msg)| text.push_str(&format!("{}: '{}'", cratename, msg)));
|
||||
|
||||
let file = format!("lintcheck-logs/{}_logs.txt", filename);
|
||||
write(file, text).unwrap();
|
||||
}
|
||||
|
|
|
@ -62,6 +62,13 @@ fn get_clap_config<'a>() -> ArgMatches<'a> {
|
|||
.value_name("CRATE")
|
||||
.long("only")
|
||||
.help("only process a single crate of the list"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("crates-toml")
|
||||
.takes_value(true)
|
||||
.value_name("CRATES-SOURCES-TOML-PATH")
|
||||
.long("crates-toml")
|
||||
.help("set the path for a crates.toml where lintcheck should read the sources from"),
|
||||
);
|
||||
|
||||
let app = App::new("Clippy developer tooling")
|
||||
|
|
|
@ -13,7 +13,9 @@ use std::path::{Path, PathBuf};
|
|||
/// Panics if `rustc_path` does not lead to a rustc repo or the files could not be read
|
||||
pub fn run(rustc_path: Option<&str>) {
|
||||
// we can unwrap here because the arg is required by clap
|
||||
let rustc_path = PathBuf::from(rustc_path.unwrap());
|
||||
let rustc_path = PathBuf::from(rustc_path.unwrap())
|
||||
.canonicalize()
|
||||
.expect("failed to get the absolute repo path");
|
||||
assert!(rustc_path.is_dir(), "path is not a directory");
|
||||
let rustc_source_basedir = rustc_path.join("compiler");
|
||||
assert!(
|
||||
|
|
|
@ -34,7 +34,7 @@ pub fn run(port: u16, lint: Option<&str>) -> ! {
|
|||
// Give some time for python to start
|
||||
thread::sleep(Duration::from_millis(500));
|
||||
// Launch browser after first export.py has completed and http.server is up
|
||||
let _ = opener::open(url);
|
||||
let _result = opener::open(url);
|
||||
});
|
||||
}
|
||||
thread::sleep(Duration::from_millis(1000));
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::path::PathBuf;
|
|||
use crate::utils::{run_lints, span_lint};
|
||||
use rustc_hir::{hir_id::CRATE_HIR_ID, Crate};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::source_map::DUMMY_SP;
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -51,6 +51,21 @@ declare_clippy_lint! {
|
|||
"common metadata is defined in `Cargo.toml`"
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct CargoCommonMetadata {
|
||||
ignore_publish: bool,
|
||||
}
|
||||
|
||||
impl CargoCommonMetadata {
|
||||
pub fn new(ignore_publish: bool) -> Self {
|
||||
Self { ignore_publish }
|
||||
}
|
||||
}
|
||||
|
||||
impl_lint_pass!(CargoCommonMetadata => [
|
||||
CARGO_COMMON_METADATA
|
||||
]);
|
||||
|
||||
fn missing_warning(cx: &LateContext<'_>, package: &cargo_metadata::Package, field: &str) {
|
||||
let message = format!("package `{}` is missing `{}` metadata", package.name, field);
|
||||
span_lint(cx, CARGO_COMMON_METADATA, DUMMY_SP, &message);
|
||||
|
@ -69,8 +84,6 @@ fn is_empty_vec(value: &[String]) -> bool {
|
|||
value.iter().all(String::is_empty)
|
||||
}
|
||||
|
||||
declare_lint_pass!(CargoCommonMetadata => [CARGO_COMMON_METADATA]);
|
||||
|
||||
impl LateLintPass<'_> for CargoCommonMetadata {
|
||||
fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) {
|
||||
if !run_lints(cx, &[CARGO_COMMON_METADATA], CRATE_HIR_ID) {
|
||||
|
@ -80,32 +93,36 @@ impl LateLintPass<'_> for CargoCommonMetadata {
|
|||
let metadata = unwrap_cargo_metadata!(cx, CARGO_COMMON_METADATA, false);
|
||||
|
||||
for package in metadata.packages {
|
||||
if is_empty_vec(&package.authors) {
|
||||
missing_warning(cx, &package, "package.authors");
|
||||
}
|
||||
// only run the lint if publish is `None` (`publish = true` or skipped entirely)
|
||||
// or if the vector isn't empty (`publish = ["something"]`)
|
||||
if package.publish.as_ref().filter(|publish| publish.is_empty()).is_none() || self.ignore_publish {
|
||||
if is_empty_vec(&package.authors) {
|
||||
missing_warning(cx, &package, "package.authors");
|
||||
}
|
||||
|
||||
if is_empty_str(&package.description) {
|
||||
missing_warning(cx, &package, "package.description");
|
||||
}
|
||||
if is_empty_str(&package.description) {
|
||||
missing_warning(cx, &package, "package.description");
|
||||
}
|
||||
|
||||
if is_empty_str(&package.license) && is_empty_path(&package.license_file) {
|
||||
missing_warning(cx, &package, "either package.license or package.license_file");
|
||||
}
|
||||
if is_empty_str(&package.license) && is_empty_path(&package.license_file) {
|
||||
missing_warning(cx, &package, "either package.license or package.license_file");
|
||||
}
|
||||
|
||||
if is_empty_str(&package.repository) {
|
||||
missing_warning(cx, &package, "package.repository");
|
||||
}
|
||||
if is_empty_str(&package.repository) {
|
||||
missing_warning(cx, &package, "package.repository");
|
||||
}
|
||||
|
||||
if is_empty_path(&package.readme) {
|
||||
missing_warning(cx, &package, "package.readme");
|
||||
}
|
||||
if is_empty_path(&package.readme) {
|
||||
missing_warning(cx, &package, "package.readme");
|
||||
}
|
||||
|
||||
if is_empty_vec(&package.keywords) {
|
||||
missing_warning(cx, &package, "package.keywords");
|
||||
}
|
||||
if is_empty_vec(&package.keywords) {
|
||||
missing_warning(cx, &package, "package.keywords");
|
||||
}
|
||||
|
||||
if is_empty_vec(&package.categories) {
|
||||
missing_warning(cx, &package, "package.categories");
|
||||
if is_empty_vec(&package.categories) {
|
||||
missing_warning(cx, &package, "package.categories");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use crate::utils::visitors::LocalUsedVisitor;
|
||||
use crate::utils::{span_lint_and_then, SpanlessEq};
|
||||
use crate::utils::{path_to_local, span_lint_and_then, SpanlessEq};
|
||||
use if_chain::if_chain;
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
|
||||
use rustc_hir::{Arm, Expr, ExprKind, Guard, HirId, Pat, PatKind, QPath, StmtKind, UnOp};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::{DefIdTree, TyCtxt};
|
||||
use rustc_middle::ty::{DefIdTree, TyCtxt, TypeckResults};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::{MultiSpan, Span};
|
||||
|
||||
|
@ -60,7 +60,7 @@ impl<'tcx> LateLintPass<'tcx> for CollapsibleMatch {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_arm(arm: &Arm<'_>, wild_outer_arm: &Arm<'_>, cx: &LateContext<'_>) {
|
||||
fn check_arm<'tcx>(arm: &Arm<'tcx>, wild_outer_arm: &Arm<'tcx>, cx: &LateContext<'tcx>) {
|
||||
if_chain! {
|
||||
let expr = strip_singleton_blocks(arm.body);
|
||||
if let ExprKind::Match(expr_in, arms_inner, _) = expr.kind;
|
||||
|
@ -72,7 +72,7 @@ fn check_arm(arm: &Arm<'_>, wild_outer_arm: &Arm<'_>, cx: &LateContext<'_>) {
|
|||
if arms_inner.iter().all(|arm| arm.guard.is_none());
|
||||
// match expression must be a local binding
|
||||
// match <local> { .. }
|
||||
if let Some(binding_id) = addr_adjusted_binding(expr_in, cx);
|
||||
if let Some(binding_id) = path_to_local(strip_ref_operators(expr_in, cx.typeck_results()));
|
||||
// one of the branches must be "wild-like"
|
||||
if let Some(wild_inner_arm_idx) = arms_inner.iter().rposition(|arm_inner| arm_is_wild_like(arm_inner, cx.tcx));
|
||||
let (wild_inner_arm, non_wild_inner_arm) =
|
||||
|
@ -84,14 +84,13 @@ fn check_arm(arm: &Arm<'_>, wild_outer_arm: &Arm<'_>, cx: &LateContext<'_>) {
|
|||
// the "wild-like" branches must be equal
|
||||
if SpanlessEq::new(cx).eq_expr(wild_inner_arm.body, wild_outer_arm.body);
|
||||
// the binding must not be used in the if guard
|
||||
let mut used_visitor = LocalUsedVisitor::new(cx, binding_id);
|
||||
if match arm.guard {
|
||||
None => true,
|
||||
Some(Guard::If(expr) | Guard::IfLet(_, expr)) => {
|
||||
!LocalUsedVisitor::new(binding_id).check_expr(expr)
|
||||
}
|
||||
Some(Guard::If(expr) | Guard::IfLet(_, expr)) => !used_visitor.check_expr(expr),
|
||||
};
|
||||
// ...or anywhere in the inner match
|
||||
if !arms_inner.iter().any(|arm| LocalUsedVisitor::new(binding_id).check_arm(arm));
|
||||
if !arms_inner.iter().any(|arm| used_visitor.check_arm(arm));
|
||||
then {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
|
@ -175,19 +174,15 @@ fn is_none_ctor(res: Res, tcx: TyCtxt<'_>) -> bool {
|
|||
false
|
||||
}
|
||||
|
||||
/// Retrieves a binding ID with optional `&` and/or `*` operators removed. (e.g. `&**foo`)
|
||||
/// Returns `None` if a non-reference type is de-referenced.
|
||||
/// For example, if `Vec` is de-referenced to a slice, `None` is returned.
|
||||
fn addr_adjusted_binding(mut expr: &Expr<'_>, cx: &LateContext<'_>) -> Option<HirId> {
|
||||
/// Removes `AddrOf` operators (`&`) or deref operators (`*`), but only if a reference type is
|
||||
/// dereferenced. An overloaded deref such as `Vec` to slice would not be removed.
|
||||
fn strip_ref_operators<'hir>(mut expr: &'hir Expr<'hir>, typeck_results: &TypeckResults<'_>) -> &'hir Expr<'hir> {
|
||||
loop {
|
||||
match expr.kind {
|
||||
ExprKind::AddrOf(_, _, e) => expr = e,
|
||||
ExprKind::Path(QPath::Resolved(None, path)) => match path.res {
|
||||
Res::Local(binding_id) => break Some(binding_id),
|
||||
_ => break None,
|
||||
},
|
||||
ExprKind::Unary(UnOp::Deref, e) if cx.typeck_results().expr_ty(e).is_ref() => expr = e,
|
||||
_ => break None,
|
||||
ExprKind::Unary(UnOp::Deref, e) if typeck_results.expr_ty(e).is_ref() => expr = e,
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
expr
|
||||
}
|
||||
|
|
|
@ -1,29 +1,47 @@
|
|||
use crate::utils::span_lint;
|
||||
use crate::utils::{fn_def_id, span_lint};
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_hir::Expr;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::Symbol;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Lints for specific trait methods defined in clippy.toml
|
||||
/// **What it does:** Denies the configured methods and functions in clippy.toml
|
||||
///
|
||||
/// **Why is this bad?** Some methods are undesirable in certain contexts,
|
||||
/// and it would be beneficial to lint for them as needed.
|
||||
/// and it's beneficial to lint for them as needed.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
/// **Known problems:** Currently, you must write each function as a
|
||||
/// fully-qualified path. This lint doesn't support aliases or reexported
|
||||
/// names; be aware that many types in `std` are actually reexports.
|
||||
///
|
||||
/// For example, if you want to disallow `Duration::as_secs`, your clippy.toml
|
||||
/// configuration would look like
|
||||
/// `disallowed-methods = ["core::time::Duration::as_secs"]` and not
|
||||
/// `disallowed-methods = ["std::time::Duration::as_secs"]` as you might expect.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// // example code where clippy issues a warning
|
||||
/// foo.bad_method(); // Foo::bad_method is disallowed in the configuration
|
||||
/// An example clippy.toml configuration:
|
||||
/// ```toml
|
||||
/// # clippy.toml
|
||||
/// disallowed-methods = ["alloc::vec::Vec::leak", "std::time::Instant::now"]
|
||||
/// ```
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// // Example code where clippy issues a warning
|
||||
/// let xs = vec![1, 2, 3, 4];
|
||||
/// xs.leak(); // Vec::leak is disallowed in the config.
|
||||
///
|
||||
/// let _now = Instant::now(); // Instant::now is disallowed in the config.
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```rust,ignore
|
||||
/// // example code which does not raise clippy warning
|
||||
/// goodStruct.bad_method(); // GoodStruct::bad_method is not disallowed
|
||||
/// // Example code which does not raise clippy warning
|
||||
/// let mut xs = Vec::new(); // Vec::new is _not_ disallowed in the config.
|
||||
/// xs.push(123); // Vec::push is _not_ disallowed in the config.
|
||||
/// ```
|
||||
pub DISALLOWED_METHOD,
|
||||
nursery,
|
||||
|
@ -50,14 +68,12 @@ impl_lint_pass!(DisallowedMethod => [DISALLOWED_METHOD]);
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for DisallowedMethod {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
if let ExprKind::MethodCall(_path, _, _args, _) = &expr.kind {
|
||||
let def_id = cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap();
|
||||
|
||||
let method_call = cx.get_def_path(def_id);
|
||||
if self.disallowed.contains(&method_call) {
|
||||
let method = method_call
|
||||
.iter()
|
||||
.map(|s| s.to_ident_string())
|
||||
if let Some(def_id) = fn_def_id(cx, expr) {
|
||||
let func_path = cx.get_def_path(def_id);
|
||||
if self.disallowed.contains(&func_path) {
|
||||
let func_path_string = func_path
|
||||
.into_iter()
|
||||
.map(Symbol::to_ident_string)
|
||||
.collect::<Vec<_>>()
|
||||
.join("::");
|
||||
|
||||
|
@ -65,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedMethod {
|
|||
cx,
|
||||
DISALLOWED_METHOD,
|
||||
expr.span,
|
||||
&format!("use of a disallowed method `{}`", method),
|
||||
&format!("use of a disallowed method `{}`", func_path_string),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use crate::utils::{get_parent_expr, span_lint, span_lint_and_note};
|
||||
use if_chain::if_chain;
|
||||
use crate::utils::{get_parent_expr, path_to_local, path_to_local_id, span_lint, span_lint_and_note};
|
||||
use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
|
||||
use rustc_hir::{def, BinOpKind, Block, Expr, ExprKind, Guard, HirId, Local, Node, QPath, Stmt, StmtKind};
|
||||
use rustc_hir::{BinOpKind, Block, Expr, ExprKind, Guard, HirId, Local, Node, Stmt, StmtKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_middle::ty;
|
||||
|
@ -72,20 +71,14 @@ impl<'tcx> LateLintPass<'tcx> for EvalOrderDependence {
|
|||
// Find a write to a local variable.
|
||||
match expr.kind {
|
||||
ExprKind::Assign(ref lhs, ..) | ExprKind::AssignOp(_, ref lhs, _) => {
|
||||
if let ExprKind::Path(ref qpath) = lhs.kind {
|
||||
if let QPath::Resolved(_, ref path) = *qpath {
|
||||
if path.segments.len() == 1 {
|
||||
if let def::Res::Local(var) = cx.qpath_res(qpath, lhs.hir_id) {
|
||||
let mut visitor = ReadVisitor {
|
||||
cx,
|
||||
var,
|
||||
write_expr: expr,
|
||||
last_expr: expr,
|
||||
};
|
||||
check_for_unsequenced_reads(&mut visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(var) = path_to_local(lhs) {
|
||||
let mut visitor = ReadVisitor {
|
||||
cx,
|
||||
var,
|
||||
write_expr: expr,
|
||||
last_expr: expr,
|
||||
};
|
||||
check_for_unsequenced_reads(&mut visitor);
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
|
@ -304,27 +297,20 @@ impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> {
|
|||
return;
|
||||
}
|
||||
|
||||
match expr.kind {
|
||||
ExprKind::Path(ref qpath) => {
|
||||
if_chain! {
|
||||
if let QPath::Resolved(None, ref path) = *qpath;
|
||||
if path.segments.len() == 1;
|
||||
if let def::Res::Local(local_id) = self.cx.qpath_res(qpath, expr.hir_id);
|
||||
if local_id == self.var;
|
||||
// Check that this is a read, not a write.
|
||||
if !is_in_assignment_position(self.cx, expr);
|
||||
then {
|
||||
span_lint_and_note(
|
||||
self.cx,
|
||||
EVAL_ORDER_DEPENDENCE,
|
||||
expr.span,
|
||||
"unsequenced read of a variable",
|
||||
Some(self.write_expr.span),
|
||||
"whether read occurs before this write depends on evaluation order"
|
||||
);
|
||||
}
|
||||
}
|
||||
if path_to_local_id(expr, self.var) {
|
||||
// Check that this is a read, not a write.
|
||||
if !is_in_assignment_position(self.cx, expr) {
|
||||
span_lint_and_note(
|
||||
self.cx,
|
||||
EVAL_ORDER_DEPENDENCE,
|
||||
expr.span,
|
||||
"unsequenced read of a variable",
|
||||
Some(self.write_expr.span),
|
||||
"whether read occurs before this write depends on evaluation order",
|
||||
);
|
||||
}
|
||||
}
|
||||
match expr.kind {
|
||||
// We're about to descend a closure. Since we don't know when (or
|
||||
// if) the closure will be evaluated, any reads in it might not
|
||||
// occur here (or ever). Like above, bail to avoid false positives.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::utils::{
|
||||
attr_by_name, attrs::is_proc_macro, is_must_use_ty, is_trait_impl_item, is_type_diagnostic_item, iter_input_pats,
|
||||
last_path_segment, match_def_path, must_use_attr, return_ty, snippet, snippet_opt, span_lint, span_lint_and_help,
|
||||
span_lint_and_then, trait_ref_of_method, type_is_unsafe_function,
|
||||
last_path_segment, match_def_path, must_use_attr, path_to_local, return_ty, snippet, snippet_opt, span_lint,
|
||||
span_lint_and_help, span_lint_and_then, trait_ref_of_method, type_is_unsafe_function,
|
||||
};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::Attribute;
|
||||
|
@ -9,7 +9,7 @@ use rustc_data_structures::fx::FxHashSet;
|
|||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::intravisit;
|
||||
use rustc_hir::{def::Res, def_id::DefId};
|
||||
use rustc_hir::{def::Res, def_id::DefId, QPath};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
|
@ -658,16 +658,14 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for DerefVisitor<'a, 'tcx> {
|
|||
|
||||
impl<'a, 'tcx> DerefVisitor<'a, 'tcx> {
|
||||
fn check_arg(&self, ptr: &hir::Expr<'_>) {
|
||||
if let hir::ExprKind::Path(ref qpath) = ptr.kind {
|
||||
if let Res::Local(id) = self.cx.qpath_res(qpath, ptr.hir_id) {
|
||||
if self.ptrs.contains(&id) {
|
||||
span_lint(
|
||||
self.cx,
|
||||
NOT_UNSAFE_PTR_ARG_DEREF,
|
||||
ptr.span,
|
||||
"this public function dereferences a raw pointer but is not marked `unsafe`",
|
||||
);
|
||||
}
|
||||
if let Some(id) = path_to_local(ptr) {
|
||||
if self.ptrs.contains(&id) {
|
||||
span_lint(
|
||||
self.cx,
|
||||
NOT_UNSAFE_PTR_ARG_DEREF,
|
||||
ptr.span,
|
||||
"this public function dereferences a raw pointer but is not marked `unsafe`",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -698,7 +696,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for StaticMutVisitor<'a, 'tcx> {
|
|||
arg.span,
|
||||
&mut tys,
|
||||
)
|
||||
&& is_mutated_static(self.cx, arg)
|
||||
&& is_mutated_static(arg)
|
||||
{
|
||||
self.mutates_static = true;
|
||||
return;
|
||||
|
@ -707,7 +705,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for StaticMutVisitor<'a, 'tcx> {
|
|||
}
|
||||
},
|
||||
Assign(ref target, ..) | AssignOp(_, ref target, _) | AddrOf(_, hir::Mutability::Mut, ref target) => {
|
||||
self.mutates_static |= is_mutated_static(self.cx, target)
|
||||
self.mutates_static |= is_mutated_static(target)
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
@ -718,12 +716,13 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for StaticMutVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_mutated_static(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> bool {
|
||||
fn is_mutated_static(e: &hir::Expr<'_>) -> bool {
|
||||
use hir::ExprKind::{Field, Index, Path};
|
||||
|
||||
match e.kind {
|
||||
Path(ref qpath) => !matches!(cx.qpath_res(qpath, e.hir_id), Res::Local(_)),
|
||||
Field(ref inner, _) | Index(ref inner, _) => is_mutated_static(cx, inner),
|
||||
Path(QPath::Resolved(_, path)) => !matches!(path.res, Res::Local(_)),
|
||||
Path(_) => true,
|
||||
Field(ref inner, _) | Index(ref inner, _) => is_mutated_static(inner),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
use crate::utils::{snippet, span_lint_and_then, visitors::LocalUsedVisitor};
|
||||
use crate::utils::{path_to_local_id, snippet, span_lint_and_then, visitors::LocalUsedVisitor};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::BindingAnnotation;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
@ -64,10 +63,11 @@ impl<'tcx> LateLintPass<'tcx> for LetIfSeq {
|
|||
if let hir::PatKind::Binding(mode, canonical_id, ident, None) = local.pat.kind;
|
||||
if let hir::StmtKind::Expr(ref if_) = expr.kind;
|
||||
if let hir::ExprKind::If(ref cond, ref then, ref else_) = if_.kind;
|
||||
if !LocalUsedVisitor::new(canonical_id).check_expr(cond);
|
||||
let mut used_visitor = LocalUsedVisitor::new(cx, canonical_id);
|
||||
if !used_visitor.check_expr(cond);
|
||||
if let hir::ExprKind::Block(ref then, _) = then.kind;
|
||||
if let Some(value) = check_assign(cx, canonical_id, &*then);
|
||||
if !LocalUsedVisitor::new(canonical_id).check_expr(value);
|
||||
if !used_visitor.check_expr(value);
|
||||
then {
|
||||
let span = stmt.span.to(if_.span);
|
||||
|
||||
|
@ -144,11 +144,9 @@ fn check_assign<'tcx>(
|
|||
if let Some(expr) = block.stmts.iter().last();
|
||||
if let hir::StmtKind::Semi(ref expr) = expr.kind;
|
||||
if let hir::ExprKind::Assign(ref var, ref value, _) = expr.kind;
|
||||
if let hir::ExprKind::Path(ref qpath) = var.kind;
|
||||
if let Res::Local(local_id) = cx.qpath_res(qpath, var.hir_id);
|
||||
if decl == local_id;
|
||||
if path_to_local_id(var, decl);
|
||||
then {
|
||||
let mut v = LocalUsedVisitor::new(decl);
|
||||
let mut v = LocalUsedVisitor::new(cx, decl);
|
||||
|
||||
if block.stmts.iter().take(block.stmts.len()-1).any(|stmt| v.check_stmt(stmt)) {
|
||||
return None;
|
||||
|
|
|
@ -5,7 +5,7 @@ use rustc_middle::lint::in_external_macro;
|
|||
use rustc_middle::ty::subst::GenericArgKind;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
use crate::utils::{implements_trait, is_must_use_func_call, is_must_use_ty, match_type, paths, span_lint_and_help};
|
||||
use crate::utils::{is_must_use_func_call, is_must_use_ty, match_type, paths, span_lint_and_help};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `let _ = <expr>`
|
||||
|
@ -125,15 +125,6 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
|
|||
|
||||
GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
|
||||
});
|
||||
let implements_drop = cx.tcx.lang_items().drop_trait().map_or(false, |drop_trait|
|
||||
init_ty.walk().any(|inner| match inner.unpack() {
|
||||
GenericArgKind::Type(inner_ty) => {
|
||||
implements_trait(cx, inner_ty, drop_trait, &[])
|
||||
},
|
||||
|
||||
GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
|
||||
})
|
||||
);
|
||||
if contains_sync_guard {
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
|
@ -144,7 +135,7 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
|
|||
"consider using an underscore-prefixed named \
|
||||
binding or dropping explicitly with `std::mem::drop`"
|
||||
)
|
||||
} else if implements_drop {
|
||||
} else if init_ty.needs_drop(cx.tcx, cx.param_env) {
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
LET_UNDERSCORE_DROP,
|
||||
|
|
|
@ -310,6 +310,7 @@ mod regex;
|
|||
mod repeat_once;
|
||||
mod returns;
|
||||
mod self_assignment;
|
||||
mod semicolon_if_nothing_returned;
|
||||
mod serde_api;
|
||||
mod shadow;
|
||||
mod single_component_path_imports;
|
||||
|
@ -687,6 +688,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
&loops::FOR_KV_MAP,
|
||||
&loops::FOR_LOOPS_OVER_FALLIBLES,
|
||||
&loops::ITER_NEXT_LOOP,
|
||||
&loops::MANUAL_FLATTEN,
|
||||
&loops::MANUAL_MEMCPY,
|
||||
&loops::MUT_RANGE_BOUND,
|
||||
&loops::NEEDLESS_COLLECT,
|
||||
|
@ -732,6 +734,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
&mem_replace::MEM_REPLACE_WITH_DEFAULT,
|
||||
&mem_replace::MEM_REPLACE_WITH_UNINIT,
|
||||
&methods::BIND_INSTEAD_OF_MAP,
|
||||
&methods::BYTES_NTH,
|
||||
&methods::CHARS_LAST_CMP,
|
||||
&methods::CHARS_NEXT_CMP,
|
||||
&methods::CLONE_DOUBLE_REF,
|
||||
|
@ -741,6 +744,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
&methods::EXPECT_USED,
|
||||
&methods::FILETYPE_IS_FILE,
|
||||
&methods::FILTER_MAP,
|
||||
&methods::FILTER_MAP_IDENTITY,
|
||||
&methods::FILTER_MAP_NEXT,
|
||||
&methods::FILTER_NEXT,
|
||||
&methods::FLAT_MAP_IDENTITY,
|
||||
|
@ -875,6 +879,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
&returns::LET_AND_RETURN,
|
||||
&returns::NEEDLESS_RETURN,
|
||||
&self_assignment::SELF_ASSIGNMENT,
|
||||
&semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED,
|
||||
&serde_api::SERDE_API_MISUSE,
|
||||
&shadow::SHADOW_REUSE,
|
||||
&shadow::SHADOW_SAME,
|
||||
|
@ -1179,7 +1184,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
store.register_early_pass(|| box redundant_else::RedundantElse);
|
||||
store.register_late_pass(|| box create_dir::CreateDir);
|
||||
store.register_early_pass(|| box needless_arbitrary_self_type::NeedlessArbitrarySelfType);
|
||||
store.register_late_pass(|| box cargo_common_metadata::CargoCommonMetadata);
|
||||
let cargo_ignore_publish = conf.cargo_ignore_publish;
|
||||
store.register_late_pass(move || box cargo_common_metadata::CargoCommonMetadata::new(cargo_ignore_publish));
|
||||
store.register_late_pass(|| box multiple_crate_versions::MultipleCrateVersions);
|
||||
store.register_late_pass(|| box wildcard_dependencies::WildcardDependencies);
|
||||
let literal_representation_lint_fraction_readability = conf.unreadable_literal_lint_fractions;
|
||||
|
@ -1236,6 +1242,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
store.register_late_pass(|| box manual_unwrap_or::ManualUnwrapOr);
|
||||
store.register_late_pass(|| box manual_ok_or::ManualOkOr);
|
||||
store.register_late_pass(|| box float_equality_without_abs::FloatEqualityWithoutAbs);
|
||||
store.register_late_pass(|| box semicolon_if_nothing_returned::SemicolonIfNothingReturned);
|
||||
store.register_late_pass(|| box async_yields_async::AsyncYieldsAsync);
|
||||
let disallowed_methods = conf.disallowed_methods.iter().cloned().collect::<FxHashSet<_>>();
|
||||
store.register_late_pass(move || box disallowed_method::DisallowedMethod::new(&disallowed_methods));
|
||||
|
@ -1290,6 +1297,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
LintId::of(&panic_unimplemented::UNIMPLEMENTED),
|
||||
LintId::of(&panic_unimplemented::UNREACHABLE),
|
||||
LintId::of(&pattern_type_mismatch::PATTERN_TYPE_MISMATCH),
|
||||
LintId::of(&semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED),
|
||||
LintId::of(&shadow::SHADOW_REUSE),
|
||||
LintId::of(&shadow::SHADOW_SAME),
|
||||
LintId::of(&strings::STRING_ADD),
|
||||
|
@ -1491,6 +1499,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
LintId::of(&loops::FOR_KV_MAP),
|
||||
LintId::of(&loops::FOR_LOOPS_OVER_FALLIBLES),
|
||||
LintId::of(&loops::ITER_NEXT_LOOP),
|
||||
LintId::of(&loops::MANUAL_FLATTEN),
|
||||
LintId::of(&loops::MANUAL_MEMCPY),
|
||||
LintId::of(&loops::MUT_RANGE_BOUND),
|
||||
LintId::of(&loops::NEEDLESS_COLLECT),
|
||||
|
@ -1524,11 +1533,13 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
LintId::of(&mem_replace::MEM_REPLACE_WITH_DEFAULT),
|
||||
LintId::of(&mem_replace::MEM_REPLACE_WITH_UNINIT),
|
||||
LintId::of(&methods::BIND_INSTEAD_OF_MAP),
|
||||
LintId::of(&methods::BYTES_NTH),
|
||||
LintId::of(&methods::CHARS_LAST_CMP),
|
||||
LintId::of(&methods::CHARS_NEXT_CMP),
|
||||
LintId::of(&methods::CLONE_DOUBLE_REF),
|
||||
LintId::of(&methods::CLONE_ON_COPY),
|
||||
LintId::of(&methods::EXPECT_FUN_CALL),
|
||||
LintId::of(&methods::FILTER_MAP_IDENTITY),
|
||||
LintId::of(&methods::FILTER_NEXT),
|
||||
LintId::of(&methods::FLAT_MAP_IDENTITY),
|
||||
LintId::of(&methods::FROM_ITER_INSTEAD_OF_COLLECT),
|
||||
|
@ -1620,7 +1631,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
LintId::of(&reference::DEREF_ADDROF),
|
||||
LintId::of(&reference::REF_IN_DEREF),
|
||||
LintId::of(®ex::INVALID_REGEX),
|
||||
LintId::of(®ex::TRIVIAL_REGEX),
|
||||
LintId::of(&repeat_once::REPEAT_ONCE),
|
||||
LintId::of(&returns::LET_AND_RETURN),
|
||||
LintId::of(&returns::NEEDLESS_RETURN),
|
||||
|
@ -1741,6 +1751,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
LintId::of(&matches::SINGLE_MATCH),
|
||||
LintId::of(&mem_replace::MEM_REPLACE_OPTION_WITH_NONE),
|
||||
LintId::of(&mem_replace::MEM_REPLACE_WITH_DEFAULT),
|
||||
LintId::of(&methods::BYTES_NTH),
|
||||
LintId::of(&methods::CHARS_LAST_CMP),
|
||||
LintId::of(&methods::CHARS_NEXT_CMP),
|
||||
LintId::of(&methods::FROM_ITER_INSTEAD_OF_COLLECT),
|
||||
|
@ -1783,7 +1794,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
LintId::of(&ranges::MANUAL_RANGE_CONTAINS),
|
||||
LintId::of(&redundant_field_names::REDUNDANT_FIELD_NAMES),
|
||||
LintId::of(&redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
|
||||
LintId::of(®ex::TRIVIAL_REGEX),
|
||||
LintId::of(&returns::LET_AND_RETURN),
|
||||
LintId::of(&returns::NEEDLESS_RETURN),
|
||||
LintId::of(&single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
|
||||
|
@ -1822,6 +1832,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
LintId::of(&lifetimes::EXTRA_UNUSED_LIFETIMES),
|
||||
LintId::of(&lifetimes::NEEDLESS_LIFETIMES),
|
||||
LintId::of(&loops::EXPLICIT_COUNTER_LOOP),
|
||||
LintId::of(&loops::MANUAL_FLATTEN),
|
||||
LintId::of(&loops::MUT_RANGE_BOUND),
|
||||
LintId::of(&loops::SINGLE_ELEMENT_LOOP),
|
||||
LintId::of(&loops::WHILE_LET_LOOP),
|
||||
|
@ -1835,6 +1846,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
LintId::of(&matches::WILDCARD_IN_OR_PATTERNS),
|
||||
LintId::of(&methods::BIND_INSTEAD_OF_MAP),
|
||||
LintId::of(&methods::CLONE_ON_COPY),
|
||||
LintId::of(&methods::FILTER_MAP_IDENTITY),
|
||||
LintId::of(&methods::FILTER_NEXT),
|
||||
LintId::of(&methods::FLAT_MAP_IDENTITY),
|
||||
LintId::of(&methods::INSPECT_FOR_EACH),
|
||||
|
@ -2011,6 +2023,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
LintId::of(&needless_borrow::NEEDLESS_BORROW),
|
||||
LintId::of(&path_buf_push_overwrite::PATH_BUF_PUSH_OVERWRITE),
|
||||
LintId::of(&redundant_pub_crate::REDUNDANT_PUB_CRATE),
|
||||
LintId::of(®ex::TRIVIAL_REGEX),
|
||||
LintId::of(&strings::STRING_LIT_AS_BYTES),
|
||||
LintId::of(&transmute::USELESS_TRANSMUTE),
|
||||
LintId::of(&use_self::USE_SELF),
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
use crate::consts::constant;
|
||||
use crate::utils::paths;
|
||||
use crate::utils::sugg::Sugg;
|
||||
use crate::utils::usage::{is_unused, mutated_variables};
|
||||
use crate::utils::usage::mutated_variables;
|
||||
use crate::utils::visitors::LocalUsedVisitor;
|
||||
use crate::utils::{
|
||||
contains_name, get_enclosing_block, get_parent_expr, get_trait_def_id, has_iter_method, higher, implements_trait,
|
||||
indent_of, is_in_panic_handler, is_integer_const, is_no_std_crate, is_refutable, is_type_diagnostic_item,
|
||||
last_path_segment, match_trait_method, match_type, match_var, multispan_sugg, single_segment_path, snippet,
|
||||
snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg,
|
||||
span_lint_and_then, sugg, SpanlessEq,
|
||||
indent_of, is_in_panic_handler, is_integer_const, is_no_std_crate, is_ok_ctor, is_refutable, is_some_ctor,
|
||||
is_type_diagnostic_item, last_path_segment, match_trait_method, match_type, multispan_sugg, path_to_local,
|
||||
path_to_local_id, paths, single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite,
|
||||
span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, sugg, SpanlessEq,
|
||||
};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast;
|
||||
|
@ -494,8 +493,40 @@ declare_clippy_lint! {
|
|||
"there is no reason to have a single element loop"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Check for unnecessary `if let` usage in a for loop
|
||||
/// where only the `Some` or `Ok` variant of the iterator element is used.
|
||||
///
|
||||
/// **Why is this bad?** It is verbose and can be simplified
|
||||
/// by first calling the `flatten` method on the `Iterator`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// let x = vec![Some(1), Some(2), Some(3)];
|
||||
/// for n in x {
|
||||
/// if let Some(n) = n {
|
||||
/// println!("{}", n);
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
/// Use instead:
|
||||
/// ```rust
|
||||
/// let x = vec![Some(1), Some(2), Some(3)];
|
||||
/// for n in x.into_iter().flatten() {
|
||||
/// println!("{}", n);
|
||||
/// }
|
||||
/// ```
|
||||
pub MANUAL_FLATTEN,
|
||||
complexity,
|
||||
"for loops over `Option`s or `Result`s with a single expression can be simplified"
|
||||
}
|
||||
|
||||
declare_lint_pass!(Loops => [
|
||||
MANUAL_MEMCPY,
|
||||
MANUAL_FLATTEN,
|
||||
NEEDLESS_RANGE_LOOP,
|
||||
EXPLICIT_ITER_LOOP,
|
||||
EXPLICIT_INTO_ITER_LOOP,
|
||||
|
@ -517,14 +548,14 @@ declare_lint_pass!(Loops => [
|
|||
impl<'tcx> LateLintPass<'tcx> for Loops {
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
if let Some((pat, arg, body)) = higher::for_loop(expr) {
|
||||
if let Some((pat, arg, body, span)) = higher::for_loop(expr) {
|
||||
// we don't want to check expanded macros
|
||||
// this check is not at the top of the function
|
||||
// since higher::for_loop expressions are marked as expansions
|
||||
if body.span.from_expansion() {
|
||||
return;
|
||||
}
|
||||
check_for_loop(cx, pat, arg, body, expr);
|
||||
check_for_loop(cx, pat, arg, body, expr, span);
|
||||
}
|
||||
|
||||
// we don't want to check expanded macros
|
||||
|
@ -707,7 +738,7 @@ fn combine_branches(b1: NeverLoopResult, b2: NeverLoopResult) -> NeverLoopResult
|
|||
fn never_loop_block(block: &Block<'_>, main_loop_id: HirId) -> NeverLoopResult {
|
||||
let stmts = block.stmts.iter().map(stmt_to_expr);
|
||||
let expr = once(block.expr.as_deref());
|
||||
let mut iter = stmts.chain(expr).filter_map(|e| e);
|
||||
let mut iter = stmts.chain(expr).flatten();
|
||||
never_loop_expr_seq(&mut iter, main_loop_id)
|
||||
}
|
||||
|
||||
|
@ -819,6 +850,7 @@ fn check_for_loop<'tcx>(
|
|||
arg: &'tcx Expr<'_>,
|
||||
body: &'tcx Expr<'_>,
|
||||
expr: &'tcx Expr<'_>,
|
||||
span: Span,
|
||||
) {
|
||||
let is_manual_memcpy_triggered = detect_manual_memcpy(cx, pat, arg, body, expr);
|
||||
if !is_manual_memcpy_triggered {
|
||||
|
@ -830,6 +862,7 @@ fn check_for_loop<'tcx>(
|
|||
check_for_mut_range_bound(cx, arg, body);
|
||||
check_for_single_element_loop(cx, pat, arg, body, expr);
|
||||
detect_same_item_push(cx, pat, arg, body, expr);
|
||||
check_manual_flatten(cx, pat, arg, body, span);
|
||||
}
|
||||
|
||||
// this function assumes the given expression is a `for` loop.
|
||||
|
@ -843,21 +876,6 @@ fn get_span_of_entire_for_loop(expr: &Expr<'_>) -> Span {
|
|||
}
|
||||
}
|
||||
|
||||
fn same_var<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, var: HirId) -> bool {
|
||||
if_chain! {
|
||||
if let ExprKind::Path(qpath) = &expr.kind;
|
||||
if let QPath::Resolved(None, path) = qpath;
|
||||
if path.segments.len() == 1;
|
||||
if let Res::Local(local_id) = cx.qpath_res(qpath, expr.hir_id);
|
||||
then {
|
||||
// our variable!
|
||||
local_id == var
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// a wrapper of `Sugg`. Besides what `Sugg` do, this removes unnecessary `0`;
|
||||
/// and also, it avoids subtracting a variable from the same one by replacing it with `0`.
|
||||
/// it exists for the convenience of the overloaded operators while normal functions can do the
|
||||
|
@ -1010,14 +1028,9 @@ fn get_details_from_idx<'tcx>(
|
|||
idx: &Expr<'_>,
|
||||
starts: &[Start<'tcx>],
|
||||
) -> Option<(StartKind<'tcx>, Offset)> {
|
||||
fn get_start<'tcx>(cx: &LateContext<'tcx>, e: &Expr<'_>, starts: &[Start<'tcx>]) -> Option<StartKind<'tcx>> {
|
||||
starts.iter().find_map(|start| {
|
||||
if same_var(cx, e, start.id) {
|
||||
Some(start.kind)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
fn get_start<'tcx>(e: &Expr<'_>, starts: &[Start<'tcx>]) -> Option<StartKind<'tcx>> {
|
||||
let id = path_to_local(e)?;
|
||||
starts.iter().find(|start| start.id == id).map(|start| start.kind)
|
||||
}
|
||||
|
||||
fn get_offset<'tcx>(cx: &LateContext<'tcx>, e: &Expr<'_>, starts: &[Start<'tcx>]) -> Option<Sugg<'static>> {
|
||||
|
@ -1026,7 +1039,7 @@ fn get_details_from_idx<'tcx>(
|
|||
ast::LitKind::Int(x, _ty) => Some(Sugg::NonParen(x.to_string().into())),
|
||||
_ => None,
|
||||
},
|
||||
ExprKind::Path(..) if get_start(cx, e, starts).is_none() => Some(Sugg::hir(cx, e, "???")),
|
||||
ExprKind::Path(..) if get_start(e, starts).is_none() => Some(Sugg::hir(cx, e, "???")),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -1034,18 +1047,18 @@ fn get_details_from_idx<'tcx>(
|
|||
match idx.kind {
|
||||
ExprKind::Binary(op, lhs, rhs) => match op.node {
|
||||
BinOpKind::Add => {
|
||||
let offset_opt = get_start(cx, lhs, starts)
|
||||
let offset_opt = get_start(lhs, starts)
|
||||
.and_then(|s| get_offset(cx, rhs, starts).map(|o| (s, o)))
|
||||
.or_else(|| get_start(cx, rhs, starts).and_then(|s| get_offset(cx, lhs, starts).map(|o| (s, o))));
|
||||
.or_else(|| get_start(rhs, starts).and_then(|s| get_offset(cx, lhs, starts).map(|o| (s, o))));
|
||||
|
||||
offset_opt.map(|(s, o)| (s, Offset::positive(o)))
|
||||
},
|
||||
BinOpKind::Sub => {
|
||||
get_start(cx, lhs, starts).and_then(|s| get_offset(cx, rhs, starts).map(|o| (s, Offset::negative(o))))
|
||||
get_start(lhs, starts).and_then(|s| get_offset(cx, rhs, starts).map(|o| (s, Offset::negative(o))))
|
||||
},
|
||||
_ => None,
|
||||
},
|
||||
ExprKind::Path(..) => get_start(cx, idx, starts).map(|s| (s, Offset::empty())),
|
||||
ExprKind::Path(..) => get_start(idx, starts).map(|s| (s, Offset::empty())),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -1062,11 +1075,10 @@ fn get_assignment<'tcx>(e: &'tcx Expr<'tcx>) -> Option<(&'tcx Expr<'tcx>, &'tcx
|
|||
/// The returned iterator yields `None` if no assignment expressions are there,
|
||||
/// filtering out the increments of the given whitelisted loop counters;
|
||||
/// because its job is to make sure there's nothing other than assignments and the increments.
|
||||
fn get_assignments<'a: 'c, 'tcx: 'c, 'c>(
|
||||
cx: &'a LateContext<'tcx>,
|
||||
fn get_assignments<'a, 'tcx>(
|
||||
Block { stmts, expr, .. }: &'tcx Block<'tcx>,
|
||||
loop_counters: &'c [Start<'tcx>],
|
||||
) -> impl Iterator<Item = Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>)>> + 'c {
|
||||
loop_counters: &'a [Start<'tcx>],
|
||||
) -> impl Iterator<Item = Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>)>> + 'a {
|
||||
// As the `filter` and `map` below do different things, I think putting together
|
||||
// just increases complexity. (cc #3188 and #4193)
|
||||
stmts
|
||||
|
@ -1078,12 +1090,14 @@ fn get_assignments<'a: 'c, 'tcx: 'c, 'c>(
|
|||
.chain((*expr).into_iter())
|
||||
.filter(move |e| {
|
||||
if let ExprKind::AssignOp(_, place, _) = e.kind {
|
||||
!loop_counters
|
||||
.iter()
|
||||
// skip the first item which should be `StartKind::Range`
|
||||
// this makes it possible to use the slice with `StartKind::Range` in the same iterator loop.
|
||||
.skip(1)
|
||||
.any(|counter| same_var(cx, place, counter.id))
|
||||
path_to_local(place).map_or(false, |id| {
|
||||
!loop_counters
|
||||
.iter()
|
||||
// skip the first item which should be `StartKind::Range`
|
||||
// this makes it possible to use the slice with `StartKind::Range` in the same iterator loop.
|
||||
.skip(1)
|
||||
.any(|counter| counter.id == id)
|
||||
})
|
||||
} else {
|
||||
true
|
||||
}
|
||||
|
@ -1140,7 +1154,7 @@ fn build_manual_memcpy_suggestion<'tcx>(
|
|||
if method.ident.name == sym!(len);
|
||||
if len_args.len() == 1;
|
||||
if let Some(arg) = len_args.get(0);
|
||||
if var_def_id(cx, arg) == var_def_id(cx, base);
|
||||
if path_to_local(arg) == path_to_local(base);
|
||||
then {
|
||||
if sugg.as_str() == end_str {
|
||||
sugg::EMPTY.into()
|
||||
|
@ -1245,7 +1259,7 @@ fn detect_manual_memcpy<'tcx>(
|
|||
if let Some(loop_counters) = get_loop_counters(cx, block, expr) {
|
||||
starts.extend(loop_counters);
|
||||
}
|
||||
iter_a = Some(get_assignments(cx, block, &starts));
|
||||
iter_a = Some(get_assignments(block, &starts));
|
||||
} else {
|
||||
iter_b = Some(get_assignment(body));
|
||||
}
|
||||
|
@ -1267,7 +1281,7 @@ fn detect_manual_memcpy<'tcx>(
|
|||
if let Some((start_right, offset_right)) = get_details_from_idx(cx, &idx_right, &starts);
|
||||
|
||||
// Source and destination must be different
|
||||
if var_def_id(cx, base_left) != var_def_id(cx, base_right);
|
||||
if path_to_local(base_left) != path_to_local(base_right);
|
||||
then {
|
||||
Some((IndexExpr { base: base_left, idx: start_left, idx_offset: offset_left },
|
||||
IndexExpr { base: base_right, idx: start_right, idx_offset: offset_right }))
|
||||
|
@ -1879,8 +1893,8 @@ fn check_for_loop_over_map_kv<'tcx>(
|
|||
let arg_span = arg.span;
|
||||
let (new_pat_span, kind, ty, mutbl) = match *cx.typeck_results().expr_ty(arg).kind() {
|
||||
ty::Ref(_, ty, mutbl) => match (&pat[0].kind, &pat[1].kind) {
|
||||
(key, _) if pat_is_wild(key, body) => (pat[1].span, "value", ty, mutbl),
|
||||
(_, value) if pat_is_wild(value, body) => (pat[0].span, "key", ty, Mutability::Not),
|
||||
(key, _) if pat_is_wild(cx, key, body) => (pat[1].span, "value", ty, mutbl),
|
||||
(_, value) if pat_is_wild(cx, value, body) => (pat[0].span, "key", ty, Mutability::Not),
|
||||
_ => return,
|
||||
},
|
||||
_ => return,
|
||||
|
@ -1953,6 +1967,77 @@ fn check_for_single_element_loop<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
/// Check for unnecessary `if let` usage in a for loop where only the `Some` or `Ok` variant of the
|
||||
/// iterator element is used.
|
||||
fn check_manual_flatten<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
pat: &'tcx Pat<'_>,
|
||||
arg: &'tcx Expr<'_>,
|
||||
body: &'tcx Expr<'_>,
|
||||
span: Span,
|
||||
) {
|
||||
if let ExprKind::Block(ref block, _) = body.kind {
|
||||
// Ensure the `if let` statement is the only expression or statement in the for-loop
|
||||
let inner_expr = if block.stmts.len() == 1 && block.expr.is_none() {
|
||||
let match_stmt = &block.stmts[0];
|
||||
if let StmtKind::Semi(inner_expr) = match_stmt.kind {
|
||||
Some(inner_expr)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else if block.stmts.is_empty() {
|
||||
block.expr
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if_chain! {
|
||||
if let Some(inner_expr) = inner_expr;
|
||||
if let ExprKind::Match(
|
||||
ref match_expr, ref match_arms, MatchSource::IfLetDesugar{ contains_else_clause: false }
|
||||
) = inner_expr.kind;
|
||||
// Ensure match_expr in `if let` statement is the same as the pat from the for-loop
|
||||
if let PatKind::Binding(_, pat_hir_id, _, _) = pat.kind;
|
||||
if path_to_local_id(match_expr, pat_hir_id);
|
||||
// Ensure the `if let` statement is for the `Some` variant of `Option` or the `Ok` variant of `Result`
|
||||
if let PatKind::TupleStruct(QPath::Resolved(None, path), _, _) = match_arms[0].pat.kind;
|
||||
let some_ctor = is_some_ctor(cx, path.res);
|
||||
let ok_ctor = is_ok_ctor(cx, path.res);
|
||||
if some_ctor || ok_ctor;
|
||||
let if_let_type = if some_ctor { "Some" } else { "Ok" };
|
||||
|
||||
then {
|
||||
// Prepare the error message
|
||||
let msg = format!("unnecessary `if let` since only the `{}` variant of the iterator element is used", if_let_type);
|
||||
|
||||
// Prepare the help message
|
||||
let mut applicability = Applicability::MaybeIncorrect;
|
||||
let arg_snippet = make_iterator_snippet(cx, arg, &mut applicability);
|
||||
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
MANUAL_FLATTEN,
|
||||
span,
|
||||
&msg,
|
||||
|diag| {
|
||||
let sugg = format!("{}.flatten()", arg_snippet);
|
||||
diag.span_suggestion(
|
||||
arg.span,
|
||||
"try",
|
||||
sugg,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
diag.span_help(
|
||||
inner_expr.span,
|
||||
"...and remove the `if let` statement in the for loop",
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct MutatePairDelegate<'a, 'tcx> {
|
||||
cx: &'a LateContext<'tcx>,
|
||||
hir_id_low: Option<HirId>,
|
||||
|
@ -2024,20 +2109,11 @@ fn mut_warn_with_span(cx: &LateContext<'_>, span: Option<Span>) {
|
|||
|
||||
fn check_for_mutability(cx: &LateContext<'_>, bound: &Expr<'_>) -> Option<HirId> {
|
||||
if_chain! {
|
||||
if let ExprKind::Path(ref qpath) = bound.kind;
|
||||
if let QPath::Resolved(None, _) = *qpath;
|
||||
if let Some(hir_id) = path_to_local(bound);
|
||||
if let Node::Binding(pat) = cx.tcx.hir().get(hir_id);
|
||||
if let PatKind::Binding(BindingAnnotation::Mutable, ..) = pat.kind;
|
||||
then {
|
||||
let res = cx.qpath_res(qpath, bound.hir_id);
|
||||
if let Res::Local(hir_id) = res {
|
||||
let node_str = cx.tcx.hir().get(hir_id);
|
||||
if_chain! {
|
||||
if let Node::Binding(pat) = node_str;
|
||||
if let PatKind::Binding(BindingAnnotation::Mutable, ..) = pat.kind;
|
||||
then {
|
||||
return Some(hir_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Some(hir_id);
|
||||
}
|
||||
}
|
||||
None
|
||||
|
@ -2069,10 +2145,12 @@ fn check_for_mutation<'tcx>(
|
|||
}
|
||||
|
||||
/// Returns `true` if the pattern is a `PatWild` or an ident prefixed with `_`.
|
||||
fn pat_is_wild<'tcx>(pat: &'tcx PatKind<'_>, body: &'tcx Expr<'_>) -> bool {
|
||||
fn pat_is_wild<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx PatKind<'_>, body: &'tcx Expr<'_>) -> bool {
|
||||
match *pat {
|
||||
PatKind::Wild => true,
|
||||
PatKind::Binding(.., ident, None) if ident.as_str().starts_with('_') => is_unused(&ident, body),
|
||||
PatKind::Binding(_, id, ident, None) if ident.as_str().starts_with('_') => {
|
||||
!LocalUsedVisitor::new(cx, id).check_expr(body)
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -2108,9 +2186,9 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
|
|||
if let QPath::Resolved(None, ref seqvar) = *seqpath;
|
||||
if seqvar.segments.len() == 1;
|
||||
then {
|
||||
let index_used_directly = same_var(self.cx, idx, self.var);
|
||||
let index_used_directly = path_to_local_id(idx, self.var);
|
||||
let indexed_indirectly = {
|
||||
let mut used_visitor = LocalUsedVisitor::new(self.var);
|
||||
let mut used_visitor = LocalUsedVisitor::new(self.cx, self.var);
|
||||
walk_expr(&mut used_visitor, idx);
|
||||
used_visitor.used
|
||||
};
|
||||
|
@ -2179,17 +2257,14 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
|
|||
|
||||
if_chain! {
|
||||
// directly using a variable
|
||||
if let ExprKind::Path(ref qpath) = expr.kind;
|
||||
if let QPath::Resolved(None, ref path) = *qpath;
|
||||
if path.segments.len() == 1;
|
||||
if let ExprKind::Path(QPath::Resolved(None, path)) = expr.kind;
|
||||
if let Res::Local(local_id) = path.res;
|
||||
then {
|
||||
if let Res::Local(local_id) = self.cx.qpath_res(qpath, expr.hir_id) {
|
||||
if local_id == self.var {
|
||||
self.nonindex = true;
|
||||
} else {
|
||||
// not the correct variable, but still a variable
|
||||
self.referenced.insert(path.segments[0].ident.name);
|
||||
}
|
||||
if local_id == self.var {
|
||||
self.nonindex = true;
|
||||
} else {
|
||||
// not the correct variable, but still a variable
|
||||
self.referenced.insert(path.segments[0].ident.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2247,7 +2322,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn is_used_inside<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, container: &'tcx Expr<'_>) -> bool {
|
||||
let def_id = match var_def_id(cx, expr) {
|
||||
let def_id = match path_to_local(expr) {
|
||||
Some(id) => id,
|
||||
None => return false,
|
||||
};
|
||||
|
@ -2260,12 +2335,11 @@ fn is_used_inside<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, container:
|
|||
}
|
||||
|
||||
fn is_iterator_used_after_while_let<'tcx>(cx: &LateContext<'tcx>, iter_expr: &'tcx Expr<'_>) -> bool {
|
||||
let def_id = match var_def_id(cx, iter_expr) {
|
||||
let def_id = match path_to_local(iter_expr) {
|
||||
Some(id) => id,
|
||||
None => return false,
|
||||
};
|
||||
let mut visitor = VarUsedAfterLoopVisitor {
|
||||
cx,
|
||||
def_id,
|
||||
iter_expr_id: iter_expr.hir_id,
|
||||
past_while_let: false,
|
||||
|
@ -2277,20 +2351,19 @@ fn is_iterator_used_after_while_let<'tcx>(cx: &LateContext<'tcx>, iter_expr: &'t
|
|||
visitor.var_used_after_while_let
|
||||
}
|
||||
|
||||
struct VarUsedAfterLoopVisitor<'a, 'tcx> {
|
||||
cx: &'a LateContext<'tcx>,
|
||||
struct VarUsedAfterLoopVisitor {
|
||||
def_id: HirId,
|
||||
iter_expr_id: HirId,
|
||||
past_while_let: bool,
|
||||
var_used_after_while_let: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Visitor<'tcx> for VarUsedAfterLoopVisitor<'a, 'tcx> {
|
||||
impl<'tcx> Visitor<'tcx> for VarUsedAfterLoopVisitor {
|
||||
type Map = Map<'tcx>;
|
||||
|
||||
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
|
||||
if self.past_while_let {
|
||||
if Some(self.def_id) == var_def_id(self.cx, expr) {
|
||||
if path_to_local_id(expr, self.def_id) {
|
||||
self.var_used_after_while_let = true;
|
||||
}
|
||||
} else if self.iter_expr_id == expr.hir_id {
|
||||
|
@ -2412,7 +2485,7 @@ impl<'a, 'tcx> Visitor<'tcx> for IncrementVisitor<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// If node is a variable
|
||||
if let Some(def_id) = var_def_id(self.cx, expr) {
|
||||
if let Some(def_id) = path_to_local(expr) {
|
||||
if let Some(parent) = get_parent_expr(self.cx, expr) {
|
||||
let state = self.states.entry(def_id).or_insert(IncrementVisitorVarState::Initial);
|
||||
if *state == IncrementVisitorVarState::IncrOnce {
|
||||
|
@ -2539,7 +2612,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// If node is the desired variable, see how it's used
|
||||
if var_def_id(self.cx, expr) == Some(self.var_id) {
|
||||
if path_to_local_id(expr, self.var_id) {
|
||||
if self.past_loop {
|
||||
self.state = InitializeVisitorState::DontWarn;
|
||||
return;
|
||||
|
@ -2586,16 +2659,6 @@ impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn var_def_id(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<HirId> {
|
||||
if let ExprKind::Path(ref qpath) = expr.kind {
|
||||
let path_res = cx.qpath_res(qpath, expr.hir_id);
|
||||
if let Res::Local(hir_id) = path_res {
|
||||
return Some(hir_id);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn is_loop(expr: &Expr<'_>) -> bool {
|
||||
matches!(expr.kind, ExprKind::Loop(..))
|
||||
}
|
||||
|
@ -2618,8 +2681,8 @@ fn is_nested(cx: &LateContext<'_>, match_expr: &Expr<'_>, iter_expr: &Expr<'_>)
|
|||
|
||||
fn is_loop_nested(cx: &LateContext<'_>, loop_expr: &Expr<'_>, iter_expr: &Expr<'_>) -> bool {
|
||||
let mut id = loop_expr.hir_id;
|
||||
let iter_name = if let Some(name) = path_name(iter_expr) {
|
||||
name
|
||||
let iter_id = if let Some(id) = path_to_local(iter_expr) {
|
||||
id
|
||||
} else {
|
||||
return true;
|
||||
};
|
||||
|
@ -2637,7 +2700,7 @@ fn is_loop_nested(cx: &LateContext<'_>, loop_expr: &Expr<'_>, iter_expr: &Expr<'
|
|||
Some(Node::Block(block)) => {
|
||||
let mut block_visitor = LoopNestVisitor {
|
||||
hir_id: id,
|
||||
iterator: iter_name,
|
||||
iterator: iter_id,
|
||||
nesting: Unknown,
|
||||
};
|
||||
walk_block(&mut block_visitor, block);
|
||||
|
@ -2665,7 +2728,7 @@ use self::Nesting::{LookFurther, RuledOut, Unknown};
|
|||
|
||||
struct LoopNestVisitor {
|
||||
hir_id: HirId,
|
||||
iterator: Symbol,
|
||||
iterator: HirId,
|
||||
nesting: Nesting,
|
||||
}
|
||||
|
||||
|
@ -2690,7 +2753,7 @@ impl<'tcx> Visitor<'tcx> for LoopNestVisitor {
|
|||
}
|
||||
match expr.kind {
|
||||
ExprKind::Assign(ref path, _, _) | ExprKind::AssignOp(_, ref path, _) => {
|
||||
if match_var(path, self.iterator) {
|
||||
if path_to_local_id(path, self.iterator) {
|
||||
self.nesting = RuledOut;
|
||||
}
|
||||
},
|
||||
|
@ -2702,8 +2765,8 @@ impl<'tcx> Visitor<'tcx> for LoopNestVisitor {
|
|||
if self.nesting != Unknown {
|
||||
return;
|
||||
}
|
||||
if let PatKind::Binding(.., span_name, _) = pat.kind {
|
||||
if self.iterator == span_name.name {
|
||||
if let PatKind::Binding(_, id, ..) = pat.kind {
|
||||
if id == self.iterator {
|
||||
self.nesting = RuledOut;
|
||||
return;
|
||||
}
|
||||
|
@ -2716,16 +2779,6 @@ impl<'tcx> Visitor<'tcx> for LoopNestVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
fn path_name(e: &Expr<'_>) -> Option<Symbol> {
|
||||
if let ExprKind::Path(QPath::Resolved(_, ref path)) = e.kind {
|
||||
let segments = &path.segments;
|
||||
if segments.len() == 1 {
|
||||
return Some(segments[0].ident.name);
|
||||
}
|
||||
};
|
||||
None
|
||||
}
|
||||
|
||||
fn check_infinite_loop<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) {
|
||||
if constant(cx, cx.typeck_results(), cond).is_some() {
|
||||
// A pure constant condition (e.g., `while false`) is not linted.
|
||||
|
@ -3087,7 +3140,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UsedCountVisitor<'a, 'tcx> {
|
|||
type Map = Map<'tcx>;
|
||||
|
||||
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
|
||||
if same_var(self.cx, expr, self.id) {
|
||||
if path_to_local_id(expr, self.id) {
|
||||
self.count += 1;
|
||||
} else {
|
||||
walk_expr(self, expr);
|
||||
|
|
|
@ -160,7 +160,7 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
|
|||
let found_idx = self.mac_refs.iter().position(|mac| import.ends_with(&mac.name));
|
||||
|
||||
if let Some(idx) = found_idx {
|
||||
let _ = self.mac_refs.remove(idx);
|
||||
self.mac_refs.remove(idx);
|
||||
let seg = import.split("::").collect::<Vec<_>>();
|
||||
|
||||
match seg.as_slice() {
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use crate::utils::{
|
||||
indent_of, is_type_diagnostic_item, match_qpath, paths, reindent_multiline, snippet_opt, span_lint_and_sugg,
|
||||
indent_of, is_type_diagnostic_item, match_qpath, path_to_local_id, paths, reindent_multiline, snippet_opt,
|
||||
span_lint_and_sugg,
|
||||
};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{def, Expr, ExprKind, PatKind, QPath};
|
||||
use rustc_hir::{Expr, ExprKind, PatKind};
|
||||
use rustc_lint::LintContext;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
|
@ -90,8 +91,6 @@ fn is_ok_wrapping(cx: &LateContext<'_>, map_expr: &Expr<'_>) -> bool {
|
|||
if let PatKind::Binding(_, param_id, ..) = body.params[0].pat.kind;
|
||||
if let ExprKind::Call(Expr { kind: ExprKind::Path(ok_path), .. }, &[ref ok_arg]) = body.value.kind;
|
||||
if match_qpath(ok_path, &paths::RESULT_OK);
|
||||
if let ExprKind::Path(QPath::Resolved(_, ok_arg_path)) = ok_arg.kind;
|
||||
if let def::Res::Local(ok_arg_path_id) = ok_arg_path.res;
|
||||
then { param_id == ok_arg_path_id } else { false }
|
||||
then { path_to_local_id(ok_arg, param_id) } else { false }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::consts::constant_simple;
|
||||
use crate::utils;
|
||||
use crate::utils::sugg;
|
||||
use crate::utils::{path_to_local_id, sugg};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{def, Arm, Expr, ExprKind, Pat, PatKind, QPath};
|
||||
use rustc_hir::{Arm, Expr, ExprKind, Pat, PatKind};
|
||||
use rustc_lint::LintContext;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
|
@ -83,9 +83,7 @@ fn lint_manual_unwrap_or<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
|||
if utils::match_qpath(unwrap_qpath, &utils::paths::OPTION_SOME)
|
||||
|| utils::match_qpath(unwrap_qpath, &utils::paths::RESULT_OK);
|
||||
if let PatKind::Binding(_, binding_hir_id, ..) = unwrap_pat.kind;
|
||||
if let ExprKind::Path(QPath::Resolved(_, body_path)) = unwrap_arm.body.kind;
|
||||
if let def::Res::Local(body_path_hir_id) = body_path.res;
|
||||
if body_path_hir_id == binding_hir_id;
|
||||
if path_to_local_id(unwrap_arm.body, binding_hir_id);
|
||||
if !utils::usage::contains_return_break_continue_macro(or_arm.body);
|
||||
then {
|
||||
Some(or_arm)
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
use crate::consts::{constant, miri_to_const, Constant};
|
||||
use crate::utils::sugg::Sugg;
|
||||
use crate::utils::usage::is_unused;
|
||||
use crate::utils::visitors::LocalUsedVisitor;
|
||||
use crate::utils::{
|
||||
expr_block, get_arg_name, get_parent_expr, implements_trait, in_macro, indent_of, is_allowed, is_expn_of,
|
||||
is_refutable, is_type_diagnostic_item, is_wild, match_qpath, match_type, match_var, meets_msrv, multispan_sugg,
|
||||
expr_block, get_parent_expr, implements_trait, in_macro, indent_of, is_allowed, is_expn_of, is_refutable,
|
||||
is_type_diagnostic_item, is_wild, match_qpath, match_type, meets_msrv, multispan_sugg, path_to_local_id,
|
||||
peel_hir_pat_refs, peel_mid_ty_refs, peel_n_hir_expr_refs, remove_blocks, snippet, snippet_block, snippet_opt,
|
||||
snippet_with_applicability, span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then,
|
||||
strip_pat_refs,
|
||||
};
|
||||
use crate::utils::{paths, search_same, SpanlessEq, SpanlessHash};
|
||||
use if_chain::if_chain;
|
||||
|
@ -616,9 +617,9 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
|
|||
if let PatKind::TupleStruct(
|
||||
QPath::Resolved(None, ref variant_name), ref args, _) = arms[0].pat.kind;
|
||||
if args.len() == 1;
|
||||
if let Some(arg) = get_arg_name(&args[0]);
|
||||
if let PatKind::Binding(_, arg, ..) = strip_pat_refs(&args[0]).kind;
|
||||
let body = remove_blocks(&arms[0].body);
|
||||
if match_var(body, arg);
|
||||
if path_to_local_id(body, arg);
|
||||
|
||||
then {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
|
@ -910,7 +911,7 @@ fn check_overlapping_arms<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'_>, arms
|
|||
}
|
||||
}
|
||||
|
||||
fn check_wild_err_arm(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
|
||||
fn check_wild_err_arm<'tcx>(cx: &LateContext<'tcx>, ex: &Expr<'tcx>, arms: &[Arm<'tcx>]) {
|
||||
let ex_ty = cx.typeck_results().expr_ty(ex).peel_refs();
|
||||
if is_type_diagnostic_item(cx, ex_ty, sym::result_type) {
|
||||
for arm in arms {
|
||||
|
@ -922,8 +923,10 @@ fn check_wild_err_arm(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
|
|||
if !matching_wild {
|
||||
// Looking for unused bindings (i.e.: `_e`)
|
||||
inner.iter().for_each(|pat| {
|
||||
if let PatKind::Binding(.., ident, None) = &pat.kind {
|
||||
if ident.as_str().starts_with('_') && is_unused(ident, arm.body) {
|
||||
if let PatKind::Binding(_, id, ident, None) = pat.kind {
|
||||
if ident.as_str().starts_with('_')
|
||||
&& !LocalUsedVisitor::new(cx, id).check_expr(arm.body)
|
||||
{
|
||||
ident_bind_name = (&ident.name.as_str()).to_string();
|
||||
matching_wild = true;
|
||||
}
|
||||
|
|
39
clippy_lints/src/methods/bytes_nth.rs
Normal file
39
clippy_lints/src/methods/bytes_nth.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
use crate::utils::{is_type_diagnostic_item, snippet_with_applicability, span_lint_and_sugg};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::sym;
|
||||
|
||||
use super::BYTES_NTH;
|
||||
|
||||
pub(super) fn lints<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'tcx [Expr<'tcx>]) {
|
||||
if_chain! {
|
||||
if let ExprKind::MethodCall(_, _, ref args, _) = expr.kind;
|
||||
let ty = cx.typeck_results().expr_ty(&iter_args[0]).peel_refs();
|
||||
let caller_type = if is_type_diagnostic_item(cx, ty, sym::string_type) {
|
||||
Some("String")
|
||||
} else if ty.is_str() {
|
||||
Some("str")
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(caller_type) = caller_type;
|
||||
then {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
BYTES_NTH,
|
||||
expr.span,
|
||||
&format!("called `.byte().nth()` on a `{}`", caller_type),
|
||||
"try",
|
||||
format!(
|
||||
"{}.as_bytes().get({})",
|
||||
snippet_with_applicability(cx, iter_args[0].span, "..", &mut applicability),
|
||||
snippet_with_applicability(cx, args[1].span, "..", &mut applicability)
|
||||
),
|
||||
applicability,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
52
clippy_lints/src/methods/filter_map_identity.rs
Normal file
52
clippy_lints/src/methods/filter_map_identity.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
use crate::utils::{match_qpath, match_trait_method, path_to_local_id, paths, span_lint_and_sugg};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::source_map::Span;
|
||||
|
||||
use super::FILTER_MAP_IDENTITY;
|
||||
|
||||
pub(super) fn check(
|
||||
cx: &LateContext<'_>,
|
||||
expr: &hir::Expr<'_>,
|
||||
filter_map_args: &[hir::Expr<'_>],
|
||||
filter_map_span: Span,
|
||||
) {
|
||||
if match_trait_method(cx, expr, &paths::ITERATOR) {
|
||||
let arg_node = &filter_map_args[1].kind;
|
||||
|
||||
let apply_lint = |message: &str| {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
FILTER_MAP_IDENTITY,
|
||||
filter_map_span.with_hi(expr.span.hi()),
|
||||
message,
|
||||
"try",
|
||||
"flatten()".to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
};
|
||||
|
||||
if_chain! {
|
||||
if let hir::ExprKind::Closure(_, _, body_id, _, _) = arg_node;
|
||||
let body = cx.tcx.hir().body(*body_id);
|
||||
|
||||
if let hir::PatKind::Binding(_, binding_id, ..) = body.params[0].pat.kind;
|
||||
if path_to_local_id(&body.value, binding_id);
|
||||
then {
|
||||
apply_lint("called `filter_map(|x| x)` on an `Iterator`");
|
||||
}
|
||||
}
|
||||
|
||||
if_chain! {
|
||||
if let hir::ExprKind::Path(ref qpath) = arg_node;
|
||||
|
||||
if match_qpath(qpath, &paths::STD_CONVERT_IDENTITY);
|
||||
|
||||
then {
|
||||
apply_lint("called `filter_map(std::convert::identity)` on an `Iterator`");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
mod bind_instead_of_map;
|
||||
mod bytes_nth;
|
||||
mod filter_map_identity;
|
||||
mod inefficient_to_string;
|
||||
mod inspect_for_each;
|
||||
mod manual_saturating_arithmetic;
|
||||
|
@ -15,8 +17,7 @@ use if_chain::if_chain;
|
|||
use rustc_ast::ast;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::{Expr, ExprKind, PatKind, QPath, TraitItem, TraitItemKind, UnOp};
|
||||
use rustc_hir::{Expr, ExprKind, PatKind, TraitItem, TraitItemKind, UnOp};
|
||||
use rustc_lint::{LateContext, LateLintPass, Lint, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::{self, TraitRef, Ty, TyS};
|
||||
|
@ -30,12 +31,12 @@ use crate::consts::{constant, Constant};
|
|||
use crate::utils::eager_or_lazy::is_lazyness_candidate;
|
||||
use crate::utils::usage::mutated_variables;
|
||||
use crate::utils::{
|
||||
contains_return, contains_ty, get_arg_name, get_parent_expr, get_trait_def_id, has_iter_method, higher,
|
||||
implements_trait, in_macro, is_copy, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment,
|
||||
match_def_path, match_qpath, match_trait_method, match_type, match_var, meets_msrv, method_calls,
|
||||
method_chain_args, paths, remove_blocks, return_ty, single_segment_path, snippet, snippet_with_applicability,
|
||||
snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, sugg,
|
||||
walk_ptrs_ty_depth, SpanlessEq,
|
||||
contains_return, contains_ty, get_parent_expr, get_trait_def_id, has_iter_method, higher, implements_trait,
|
||||
in_macro, is_copy, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path,
|
||||
match_qpath, match_trait_method, match_type, meets_msrv, method_calls, method_chain_args, path_to_local_id, paths,
|
||||
remove_blocks, return_ty, single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite,
|
||||
span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, strip_pat_refs, sugg, walk_ptrs_ty_depth,
|
||||
SpanlessEq,
|
||||
};
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -1467,6 +1468,51 @@ declare_clippy_lint! {
|
|||
"using `.inspect().for_each()`, which can be replaced with `.for_each()`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of `filter_map(|x| x)`.
|
||||
///
|
||||
/// **Why is this bad?** Readability, this can be written more concisely by using `flatten`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// # let iter = vec![Some(1)].into_iter();
|
||||
/// iter.filter_map(|x| x);
|
||||
/// ```
|
||||
/// Use instead:
|
||||
/// ```rust
|
||||
/// # let iter = vec![Some(1)].into_iter();
|
||||
/// iter.flatten();
|
||||
/// ```
|
||||
pub FILTER_MAP_IDENTITY,
|
||||
complexity,
|
||||
"call to `filter_map` where `flatten` is sufficient"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for the use of `.bytes().nth()`.
|
||||
///
|
||||
/// **Why is this bad?** `.as_bytes().get()` is more efficient and more
|
||||
/// readable.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// let _ = "Hello".bytes().nth(3);
|
||||
///
|
||||
/// // Good
|
||||
/// let _ = "Hello".as_bytes().get(3);
|
||||
/// ```
|
||||
pub BYTES_NTH,
|
||||
style,
|
||||
"replace `.bytes().nth()` with `.as_bytes().get()`"
|
||||
}
|
||||
|
||||
pub struct Methods {
|
||||
msrv: Option<RustcVersion>,
|
||||
}
|
||||
|
@ -1504,6 +1550,7 @@ impl_lint_pass!(Methods => [
|
|||
FILTER_NEXT,
|
||||
SKIP_WHILE_NEXT,
|
||||
FILTER_MAP,
|
||||
FILTER_MAP_IDENTITY,
|
||||
MANUAL_FILTER_MAP,
|
||||
MANUAL_FIND_MAP,
|
||||
FILTER_MAP_NEXT,
|
||||
|
@ -1513,6 +1560,7 @@ impl_lint_pass!(Methods => [
|
|||
ITER_NEXT_SLICE,
|
||||
ITER_NTH,
|
||||
ITER_NTH_ZERO,
|
||||
BYTES_NTH,
|
||||
ITER_SKIP_NEXT,
|
||||
GET_UNWRAP,
|
||||
STRING_EXTEND_CHARS,
|
||||
|
@ -1590,6 +1638,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
|||
["extend", ..] => lint_extend(cx, expr, arg_lists[0]),
|
||||
["nth", "iter"] => lint_iter_nth(cx, expr, &arg_lists, false),
|
||||
["nth", "iter_mut"] => lint_iter_nth(cx, expr, &arg_lists, true),
|
||||
["nth", "bytes"] => bytes_nth::lints(cx, expr, &arg_lists[1]),
|
||||
["nth", ..] => lint_iter_nth_zero(cx, expr, arg_lists[0]),
|
||||
["step_by", ..] => lint_step_by(cx, expr, arg_lists[0]),
|
||||
["next", "skip"] => lint_iter_skip_next(cx, expr, arg_lists[1]),
|
||||
|
@ -1597,7 +1646,10 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
|||
["as_ref"] => lint_asref(cx, expr, "as_ref", arg_lists[0]),
|
||||
["as_mut"] => lint_asref(cx, expr, "as_mut", arg_lists[0]),
|
||||
["fold", ..] => lint_unnecessary_fold(cx, expr, arg_lists[0], method_spans[0]),
|
||||
["filter_map", ..] => unnecessary_filter_map::lint(cx, expr, arg_lists[0]),
|
||||
["filter_map", ..] => {
|
||||
unnecessary_filter_map::lint(cx, expr, arg_lists[0]);
|
||||
filter_map_identity::check(cx, expr, arg_lists[0], method_spans[0]);
|
||||
},
|
||||
["count", "map"] => lint_suspicious_map(cx, expr),
|
||||
["assume_init"] => lint_maybe_uninit(cx, &arg_lists[0][0], expr),
|
||||
["unwrap_or", arith @ ("checked_add" | "checked_sub" | "checked_mul")] => {
|
||||
|
@ -2181,7 +2233,10 @@ fn lint_expect_fun_call(
|
|||
span_replace_word,
|
||||
&format!("use of `{}` followed by a function call", name),
|
||||
"try this",
|
||||
format!("unwrap_or_else({} {{ panic!(\"{{}}\", {}) }})", closure_args, arg_root_snippet),
|
||||
format!(
|
||||
"unwrap_or_else({} {{ panic!(\"{{}}\", {}) }})",
|
||||
closure_args, arg_root_snippet
|
||||
),
|
||||
applicability,
|
||||
);
|
||||
}
|
||||
|
@ -2394,11 +2449,12 @@ fn lint_unnecessary_fold(cx: &LateContext<'_>, expr: &hir::Expr<'_>, fold_args:
|
|||
if bin_op.node == op;
|
||||
|
||||
// Extract the names of the two arguments to the closure
|
||||
if let Some(first_arg_ident) = get_arg_name(&closure_body.params[0].pat);
|
||||
if let Some(second_arg_ident) = get_arg_name(&closure_body.params[1].pat);
|
||||
if let [param_a, param_b] = closure_body.params;
|
||||
if let PatKind::Binding(_, first_arg_id, ..) = strip_pat_refs(¶m_a.pat).kind;
|
||||
if let PatKind::Binding(_, second_arg_id, second_arg_ident, _) = strip_pat_refs(¶m_b.pat).kind;
|
||||
|
||||
if match_var(&*left_expr, first_arg_ident);
|
||||
if replacement_has_args || match_var(&*right_expr, second_arg_ident);
|
||||
if path_to_local_id(left_expr, first_arg_id);
|
||||
if replacement_has_args || path_to_local_id(right_expr, second_arg_id);
|
||||
|
||||
then {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
|
@ -3066,10 +3122,8 @@ fn lint_filter_map<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, is_f
|
|||
};
|
||||
// let the filter closure arg and the map closure arg be equal
|
||||
if_chain! {
|
||||
if let ExprKind::Path(QPath::Resolved(None, a_path)) = a_path.kind;
|
||||
if let ExprKind::Path(QPath::Resolved(None, b_path)) = b.kind;
|
||||
if a_path.res == Res::Local(filter_param_id);
|
||||
if b_path.res == Res::Local(map_param_id);
|
||||
if path_to_local_id(a_path, filter_param_id);
|
||||
if path_to_local_id(b, map_param_id);
|
||||
if TyS::same_type(cx.typeck_results().expr_ty_adjusted(a), cx.typeck_results().expr_ty_adjusted(b));
|
||||
then {
|
||||
return true;
|
||||
|
@ -3253,8 +3307,9 @@ fn lint_search_is_some<'tcx>(
|
|||
then {
|
||||
if let hir::PatKind::Ref(..) = closure_arg.pat.kind {
|
||||
Some(search_snippet.replacen('&', "", 1))
|
||||
} else if let Some(name) = get_arg_name(&closure_arg.pat) {
|
||||
Some(search_snippet.replace(&format!("*{}", name), &name.as_str()))
|
||||
} else if let PatKind::Binding(_, _, ident, _) = strip_pat_refs(&closure_arg.pat).kind {
|
||||
let name = &*ident.name.as_str();
|
||||
Some(search_snippet.replace(&format!("*{}", name), name))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -3686,9 +3741,7 @@ fn lint_option_as_ref_deref<'tcx>(
|
|||
hir::ExprKind::MethodCall(_, _, args, _) => {
|
||||
if_chain! {
|
||||
if args.len() == 1;
|
||||
if let hir::ExprKind::Path(qpath) = &args[0].kind;
|
||||
if let hir::def::Res::Local(local_id) = cx.qpath_res(qpath, args[0].hir_id);
|
||||
if closure_body.params[0].pat.hir_id == local_id;
|
||||
if path_to_local_id(&args[0], closure_body.params[0].pat.hir_id);
|
||||
let adj = cx
|
||||
.typeck_results()
|
||||
.expr_adjustments(&args[0])
|
||||
|
@ -3708,10 +3761,8 @@ fn lint_option_as_ref_deref<'tcx>(
|
|||
if_chain! {
|
||||
if let hir::ExprKind::Unary(hir::UnOp::Deref, ref inner1) = inner.kind;
|
||||
if let hir::ExprKind::Unary(hir::UnOp::Deref, ref inner2) = inner1.kind;
|
||||
if let hir::ExprKind::Path(ref qpath) = inner2.kind;
|
||||
if let hir::def::Res::Local(local_id) = cx.qpath_res(qpath, inner2.hir_id);
|
||||
then {
|
||||
closure_body.params[0].pat.hir_id == local_id
|
||||
path_to_local_id(inner2, closure_body.params[0].pat.hir_id)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
@ -4092,20 +4143,54 @@ fn lint_from_iter(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<
|
|||
if implements_trait(cx, ty, from_iter_id, &[]) && implements_trait(cx, arg_ty, iter_id, &[]);
|
||||
then {
|
||||
// `expr` implements `FromIterator` trait
|
||||
let iter_expr = snippet(cx, args[0].span, "..");
|
||||
let iter_expr = sugg::Sugg::hir(cx, &args[0], "..").maybe_par();
|
||||
let turbofish = extract_turbofish(cx, expr, ty);
|
||||
let sugg = format!("{}.collect::<{}>()", iter_expr, turbofish);
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
FROM_ITER_INSTEAD_OF_COLLECT,
|
||||
expr.span,
|
||||
"usage of `FromIterator::from_iter`",
|
||||
"use `.collect()` instead of `::from_iter()`",
|
||||
format!("{}.collect()", iter_expr),
|
||||
sugg,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_turbofish(cx: &LateContext<'_>, expr: &hir::Expr<'_>, ty: Ty<'tcx>) -> String {
|
||||
if_chain! {
|
||||
let call_site = expr.span.source_callsite();
|
||||
if let Ok(snippet) = cx.sess().source_map().span_to_snippet(call_site);
|
||||
let snippet_split = snippet.split("::").collect::<Vec<_>>();
|
||||
if let Some((_, elements)) = snippet_split.split_last();
|
||||
|
||||
then {
|
||||
// is there a type specifier? (i.e.: like `<u32>` in `collections::BTreeSet::<u32>::`)
|
||||
if let Some(type_specifier) = snippet_split.iter().find(|e| e.starts_with('<') && e.ends_with('>')) {
|
||||
// remove the type specifier from the path elements
|
||||
let without_ts = elements.iter().filter_map(|e| {
|
||||
if e == type_specifier { None } else { Some((*e).to_string()) }
|
||||
}).collect::<Vec<_>>();
|
||||
// join and add the type specifier at the end (i.e.: `collections::BTreeSet<u32>`)
|
||||
format!("{}{}", without_ts.join("::"), type_specifier)
|
||||
} else {
|
||||
// type is not explicitly specified so wildcards are needed
|
||||
// i.e.: 2 wildcards in `std::collections::BTreeMap<&i32, &char>`
|
||||
let ty_str = ty.to_string();
|
||||
let start = ty_str.find('<').unwrap_or(0);
|
||||
let end = ty_str.find('>').unwrap_or_else(|| ty_str.len());
|
||||
let nb_wildcard = ty_str[start..end].split(',').count();
|
||||
let wildcards = format!("_{}", ", _".repeat(nb_wildcard - 1));
|
||||
format!("{}<{}>", elements.join("::"), wildcards)
|
||||
}
|
||||
} else {
|
||||
ty.to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fn_header_equals(expected: hir::FnHeader, actual: hir::FnHeader) -> bool {
|
||||
expected.constness == actual.constness
|
||||
&& expected.unsafety == actual.unsafety
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
use crate::utils::paths;
|
||||
use crate::utils::usage::mutated_variables;
|
||||
use crate::utils::{match_qpath, match_trait_method, span_lint};
|
||||
use crate::utils::{match_qpath, match_trait_method, path_to_local_id, paths, span_lint};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::hir::map::Map;
|
||||
|
@ -59,14 +57,8 @@ fn check_expression<'tcx>(cx: &LateContext<'tcx>, arg_id: hir::HirId, expr: &'tc
|
|||
if let hir::ExprKind::Path(ref path) = func.kind;
|
||||
then {
|
||||
if match_qpath(path, &paths::OPTION_SOME) {
|
||||
if_chain! {
|
||||
if let hir::ExprKind::Path(path) = &args[0].kind;
|
||||
if let Res::Local(ref local) = cx.qpath_res(path, args[0].hir_id);
|
||||
then {
|
||||
if arg_id == *local {
|
||||
return (false, false)
|
||||
}
|
||||
}
|
||||
if path_to_local_id(&args[0], arg_id) {
|
||||
return (false, false)
|
||||
}
|
||||
return (true, false);
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for MutVisitor<'a, 'tcx> {
|
|||
return;
|
||||
}
|
||||
|
||||
if let Some((_, arg, body)) = higher::for_loop(expr) {
|
||||
if let Some((_, arg, body, _)) = higher::for_loop(expr) {
|
||||
// A `for` loop lowers to:
|
||||
// ```rust
|
||||
// match ::std::iter::Iterator::next(&mut iter) {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
|
||||
use rustc_hir::{Body, Expr, ExprKind, LangItem, MatchSource, QPath};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::ty::DefIdTree;
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::sym;
|
||||
|
@ -160,7 +158,7 @@ fn is_some_or_ok_call<'a>(
|
|||
// Check outer expression matches CALL_IDENT(ARGUMENT) format
|
||||
if let ExprKind::Call(path, args) = &expr.kind;
|
||||
if let ExprKind::Path(QPath::Resolved(None, path)) = &path.kind;
|
||||
if is_some_ctor(cx, path.res) || is_ok_ctor(cx, path.res);
|
||||
if utils::is_some_ctor(cx, path.res) || utils::is_ok_ctor(cx, path.res);
|
||||
|
||||
// Extract inner expression from ARGUMENT
|
||||
if let ExprKind::Match(inner_expr_with_q, _, MatchSource::TryDesugar) = &args[0].kind;
|
||||
|
@ -208,25 +206,3 @@ fn is_some_or_ok_call<'a>(
|
|||
fn has_implicit_error_from(cx: &LateContext<'_>, entire_expr: &Expr<'_>, inner_result_expr: &Expr<'_>) -> bool {
|
||||
return cx.typeck_results().expr_ty(entire_expr) != cx.typeck_results().expr_ty(inner_result_expr);
|
||||
}
|
||||
|
||||
fn is_ok_ctor(cx: &LateContext<'_>, res: Res) -> bool {
|
||||
if let Some(ok_id) = cx.tcx.lang_items().result_ok_variant() {
|
||||
if let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), id) = res {
|
||||
if let Some(variant_id) = cx.tcx.parent(id) {
|
||||
return variant_id == ok_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn is_some_ctor(cx: &LateContext<'_>, res: Res) -> bool {
|
||||
if let Some(some_id) = cx.tcx.lang_items().option_some_variant() {
|
||||
if let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), id) = res {
|
||||
if let Some(variant_id) = cx.tcx.parent(id) {
|
||||
return variant_id == some_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
|
|
@ -442,7 +442,7 @@ fn check_reversed_empty_range(cx: &LateContext<'_>, expr: &Expr<'_>) {
|
|||
let mut cur_expr = expr;
|
||||
while let Some(parent_expr) = get_parent_expr(cx, cur_expr) {
|
||||
match higher::for_loop(parent_expr) {
|
||||
Some((_, args, _)) if args.hir_id == expr.hir_id => return true,
|
||||
Some((_, args, _, _)) if args.hir_id == expr.hir_id => return true,
|
||||
_ => cur_expr = parent_expr,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,14 +35,16 @@ declare_clippy_lint! {
|
|||
/// `str::starts_with`, `str::ends_with` or `std::contains` or other `str`
|
||||
/// methods.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
/// **Known problems:** If the same regex is going to be applied to multiple
|
||||
/// inputs, the precomputations done by `Regex` construction can give
|
||||
/// significantly better performance than any of the `str`-based methods.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// Regex::new("^foobar")
|
||||
/// ```
|
||||
pub TRIVIAL_REGEX,
|
||||
style,
|
||||
nursery,
|
||||
"trivial regular expressions"
|
||||
}
|
||||
|
||||
|
|
66
clippy_lints/src/semicolon_if_nothing_returned.rs
Normal file
66
clippy_lints/src/semicolon_if_nothing_returned.rs
Normal file
|
@ -0,0 +1,66 @@
|
|||
use crate::utils::{in_macro, snippet_with_macro_callsite, span_lint_and_sugg, sugg};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Block, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Looks for blocks of expressions and fires if the last expression returns `()`
|
||||
/// but is not followed by a semicolon.
|
||||
///
|
||||
/// **Why is this bad?** The semicolon might be optional but when
|
||||
/// extending the block with new code, it doesn't require a change in previous last line.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// fn main() {
|
||||
/// println!("Hello world")
|
||||
/// }
|
||||
/// ```
|
||||
/// Use instead:
|
||||
/// ```rust
|
||||
/// fn main() {
|
||||
/// println!("Hello world");
|
||||
/// }
|
||||
/// ```
|
||||
pub SEMICOLON_IF_NOTHING_RETURNED,
|
||||
restriction,
|
||||
"add a semicolon if nothing is returned"
|
||||
}
|
||||
|
||||
declare_lint_pass!(SemicolonIfNothingReturned => [SEMICOLON_IF_NOTHING_RETURNED]);
|
||||
|
||||
impl LateLintPass<'_> for SemicolonIfNothingReturned {
|
||||
fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {
|
||||
if_chain! {
|
||||
if !in_macro(block.span);
|
||||
if let Some(expr) = block.expr;
|
||||
let t_expr = cx.typeck_results().expr_ty(expr);
|
||||
if t_expr.is_unit();
|
||||
if let snippet = snippet_with_macro_callsite(cx, expr.span, "}");
|
||||
if !snippet.ends_with('}');
|
||||
then {
|
||||
// filter out the desugared `for` loop
|
||||
if let ExprKind::DropTemps(..) = &expr.kind {
|
||||
return;
|
||||
}
|
||||
|
||||
let sugg = sugg::Sugg::hir_with_macro_callsite(cx, &expr, "..");
|
||||
let suggestion = format!("{0};", sugg);
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
SEMICOLON_IF_NOTHING_RETURNED,
|
||||
expr.span.source_callsite(),
|
||||
"consider adding a `;` to the last statement for consistent formatting",
|
||||
"add a `;` here",
|
||||
suggestion,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
use crate::utils::{match_def_path, match_trait_method, paths, span_lint};
|
||||
use crate::utils::{match_def_path, match_trait_method, path_to_local_id, paths, span_lint};
|
||||
use if_chain::if_chain;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::{Expr, ExprKind, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
|
@ -89,14 +88,12 @@ impl LateLintPass<'_> for ToStringInDisplay {
|
|||
|
||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||
if_chain! {
|
||||
if self.in_display_impl;
|
||||
if let Some(self_hir_id) = self.self_hir_id;
|
||||
if let ExprKind::MethodCall(ref path, _, args, _) = expr.kind;
|
||||
if path.ident.name == sym!(to_string);
|
||||
if match_trait_method(cx, expr, &paths::TO_STRING);
|
||||
if self.in_display_impl;
|
||||
if let ExprKind::Path(ref qpath) = args[0].kind;
|
||||
if let Res::Local(hir_id) = cx.qpath_res(qpath, args[0].hir_id);
|
||||
if let Some(self_hir_id) = self.self_hir_id;
|
||||
if hir_id == self_hir_id;
|
||||
if path_to_local_id(&args[0], self_hir_id);
|
||||
then {
|
||||
span_lint(
|
||||
cx,
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
use if_chain::if_chain;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::intravisit::{walk_path, NestedVisitorMap, Visitor};
|
||||
use rustc_hir::{HirId, Impl, ImplItem, ImplItemKind, ItemKind, Path};
|
||||
use rustc_hir::{Impl, ImplItem, ImplItemKind, ItemKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
use crate::utils::span_lint_and_help;
|
||||
use crate::utils::visitors::LocalUsedVisitor;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks methods that contain a `self` argument but don't use it
|
||||
|
@ -56,13 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedSelf {
|
|||
then {
|
||||
let self_param = &body.params[0];
|
||||
let self_hir_id = self_param.pat.hir_id;
|
||||
let mut visitor = UnusedSelfVisitor {
|
||||
cx,
|
||||
uses_self: false,
|
||||
self_hir_id: &self_hir_id,
|
||||
};
|
||||
visitor.visit_body(body);
|
||||
if !visitor.uses_self {
|
||||
if !LocalUsedVisitor::new(cx, self_hir_id).check_body(body) {
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
UNUSED_SELF,
|
||||
|
@ -77,28 +69,3 @@ impl<'tcx> LateLintPass<'tcx> for UnusedSelf {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct UnusedSelfVisitor<'a, 'tcx> {
|
||||
cx: &'a LateContext<'tcx>,
|
||||
uses_self: bool,
|
||||
self_hir_id: &'a HirId,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Visitor<'tcx> for UnusedSelfVisitor<'a, 'tcx> {
|
||||
type Map = Map<'tcx>;
|
||||
|
||||
fn visit_path(&mut self, path: &'tcx Path<'_>, _id: HirId) {
|
||||
if self.uses_self {
|
||||
// This function already uses `self`
|
||||
return;
|
||||
}
|
||||
if let Res::Local(hir_id) = &path.res {
|
||||
self.uses_self = self.self_hir_id == hir_id
|
||||
}
|
||||
walk_path(self, path);
|
||||
}
|
||||
|
||||
fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
|
||||
NestedVisitorMap::OnlyBodies(self.cx.tcx.hir())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,10 +169,12 @@ define_Conf! {
|
|||
(max_fn_params_bools, "max_fn_params_bools": u64, 3),
|
||||
/// Lint: WILDCARD_IMPORTS. Whether to allow certain wildcard imports (prelude, super in tests).
|
||||
(warn_on_all_wildcard_imports, "warn_on_all_wildcard_imports": bool, false),
|
||||
/// Lint: DISALLOWED_METHOD. The list of blacklisted methods to lint about. NB: `bar` is not here since it has legitimate uses
|
||||
/// Lint: DISALLOWED_METHOD. The list of disallowed methods, written as fully qualified paths.
|
||||
(disallowed_methods, "disallowed_methods": Vec<String>, Vec::<String>::new()),
|
||||
/// Lint: UNREADABLE_LITERAL. Should the fraction of a decimal be linted to include separators.
|
||||
(unreadable_literal_lint_fractions, "unreadable_literal_lint_fractions": bool, true),
|
||||
/// Lint: _CARGO_COMMON_METADATA. For internal testing only, ignores the current `publish` settings in the Cargo manifest.
|
||||
(cargo_ignore_publish, "cargo_ignore_publish": bool, false),
|
||||
}
|
||||
|
||||
impl Default for Conf {
|
||||
|
|
|
@ -9,6 +9,7 @@ use rustc_ast::ast;
|
|||
use rustc_hir as hir;
|
||||
use rustc_hir::{BorrowKind, Expr, ExprKind, StmtKind, UnOp};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::source_map::Span;
|
||||
|
||||
/// Converts a hir binary operator to the corresponding `ast` type.
|
||||
#[must_use]
|
||||
|
@ -133,11 +134,11 @@ pub fn is_from_for_desugar(local: &hir::Local<'_>) -> bool {
|
|||
false
|
||||
}
|
||||
|
||||
/// Recover the essential nodes of a desugared for loop:
|
||||
/// `for pat in arg { body }` becomes `(pat, arg, body)`.
|
||||
/// Recover the essential nodes of a desugared for loop as well as the entire span:
|
||||
/// `for pat in arg { body }` becomes `(pat, arg, body)`. Return `(pat, arg, body, span)`.
|
||||
pub fn for_loop<'tcx>(
|
||||
expr: &'tcx hir::Expr<'tcx>,
|
||||
) -> Option<(&hir::Pat<'_>, &'tcx hir::Expr<'tcx>, &'tcx hir::Expr<'tcx>)> {
|
||||
) -> Option<(&hir::Pat<'_>, &'tcx hir::Expr<'tcx>, &'tcx hir::Expr<'tcx>, Span)> {
|
||||
if_chain! {
|
||||
if let hir::ExprKind::Match(ref iterexpr, ref arms, hir::MatchSource::ForLoopDesugar) = expr.kind;
|
||||
if let hir::ExprKind::Call(_, ref iterargs) = iterexpr.kind;
|
||||
|
@ -148,7 +149,7 @@ pub fn for_loop<'tcx>(
|
|||
if let hir::StmtKind::Local(ref local) = let_stmt.kind;
|
||||
if let hir::StmtKind::Expr(ref expr) = body.kind;
|
||||
then {
|
||||
return Some((&*local.pat, &iterargs[0], expr));
|
||||
return Some((&*local.pat, &iterargs[0], expr, arms[0].span));
|
||||
}
|
||||
}
|
||||
None
|
||||
|
|
|
@ -841,15 +841,13 @@ pub fn check_path(cx: &LateContext<'_>, path: &[&str]) -> bool {
|
|||
// implementations of native types. Check lang items.
|
||||
let path_syms: Vec<_> = path.iter().map(|p| Symbol::intern(p)).collect();
|
||||
let lang_items = cx.tcx.lang_items();
|
||||
for lang_item in lang_items.items() {
|
||||
if let Some(def_id) = lang_item {
|
||||
let lang_item_path = cx.get_def_path(*def_id);
|
||||
if path_syms.starts_with(&lang_item_path) {
|
||||
if let [item] = &path_syms[lang_item_path.len()..] {
|
||||
for child in cx.tcx.item_children(*def_id) {
|
||||
if child.ident.name == *item {
|
||||
return true;
|
||||
}
|
||||
for item_def_id in lang_items.items().iter().flatten() {
|
||||
let lang_item_path = cx.get_def_path(*item_def_id);
|
||||
if path_syms.starts_with(&lang_item_path) {
|
||||
if let [item] = &path_syms[lang_item_path.len()..] {
|
||||
for child in cx.tcx.item_children(*item_def_id) {
|
||||
if child.ident.name == *item {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ use rustc_ast::ast::{self, Attribute, LitKind};
|
|||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||
use rustc_hir::Node;
|
||||
|
@ -49,7 +49,7 @@ use rustc_lint::{LateContext, Level, Lint, LintContext};
|
|||
use rustc_middle::hir::exports::Export;
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
|
||||
use rustc_middle::ty::{self, layout::IntegerExt, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_middle::ty::{self, layout::IntegerExt, DefIdTree, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::hygiene::{ExpnKind, MacroKind};
|
||||
|
@ -306,6 +306,22 @@ pub fn match_path_ast(path: &ast::Path, segments: &[&str]) -> bool {
|
|||
.all(|(a, b)| a.ident.name.as_str() == *b)
|
||||
}
|
||||
|
||||
/// If the expression is a path to a local, returns the canonical `HirId` of the local.
|
||||
pub fn path_to_local(expr: &Expr<'_>) -> Option<HirId> {
|
||||
if let ExprKind::Path(QPath::Resolved(None, ref path)) = expr.kind {
|
||||
if let Res::Local(id) = path.res {
|
||||
return Some(id);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns true if the expression is a path to a local with the specified `HirId`.
|
||||
/// Use this function to see if an expression matches a function argument or a match binding.
|
||||
pub fn path_to_local_id(expr: &Expr<'_>, id: HirId) -> bool {
|
||||
path_to_local(expr) == Some(id)
|
||||
}
|
||||
|
||||
/// Gets the definition associated to a path.
|
||||
#[allow(clippy::shadow_unrelated)] // false positive #6563
|
||||
pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
|
||||
|
@ -1134,9 +1150,7 @@ pub fn is_try<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {
|
|||
if let PatKind::TupleStruct(ref path, ref pat, None) = arm.pat.kind;
|
||||
if match_qpath(path, &paths::RESULT_OK[1..]);
|
||||
if let PatKind::Binding(_, hir_id, _, None) = pat[0].kind;
|
||||
if let ExprKind::Path(QPath::Resolved(None, ref path)) = arm.body.kind;
|
||||
if let Res::Local(lid) = path.res;
|
||||
if lid == hir_id;
|
||||
if path_to_local_id(arm.body, hir_id);
|
||||
then {
|
||||
return true;
|
||||
}
|
||||
|
@ -1180,12 +1194,11 @@ pub fn is_allowed(cx: &LateContext<'_>, lint: &'static Lint, id: HirId) -> bool
|
|||
cx.tcx.lint_level_at_node(lint, id).0 == Level::Allow
|
||||
}
|
||||
|
||||
pub fn get_arg_name(pat: &Pat<'_>) -> Option<Symbol> {
|
||||
match pat.kind {
|
||||
PatKind::Binding(.., ident, None) => Some(ident.name),
|
||||
PatKind::Ref(ref subpat, _) => get_arg_name(subpat),
|
||||
_ => None,
|
||||
pub fn strip_pat_refs<'hir>(mut pat: &'hir Pat<'hir>) -> &'hir Pat<'hir> {
|
||||
while let PatKind::Ref(subpat, _) = pat.kind {
|
||||
pat = subpat;
|
||||
}
|
||||
pat
|
||||
}
|
||||
|
||||
pub fn int_bits(tcx: TyCtxt<'_>, ity: ty::IntTy) -> u64 {
|
||||
|
@ -1702,6 +1715,30 @@ pub fn is_hir_ty_cfg_dependant(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
/// Check if the resolution of a given path is an `Ok` variant of `Result`.
|
||||
pub fn is_ok_ctor(cx: &LateContext<'_>, res: Res) -> bool {
|
||||
if let Some(ok_id) = cx.tcx.lang_items().result_ok_variant() {
|
||||
if let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), id) = res {
|
||||
if let Some(variant_id) = cx.tcx.parent(id) {
|
||||
return variant_id == ok_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Check if the resolution of a given path is a `Some` variant of `Option`.
|
||||
pub fn is_some_ctor(cx: &LateContext<'_>, res: Res) -> bool {
|
||||
if let Some(some_id) = cx.tcx.lang_items().option_some_variant() {
|
||||
if let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), id) = res {
|
||||
if let Some(variant_id) = cx.tcx.parent(id) {
|
||||
return variant_id == some_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{reindent_multiline, without_block_comments};
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
use crate::utils;
|
||||
use crate::utils::match_var;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::intravisit;
|
||||
use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
|
||||
use rustc_hir::intravisit::{NestedVisitorMap, Visitor};
|
||||
use rustc_hir::{Expr, ExprKind, HirId, Path};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_middle::ty;
|
||||
use rustc_span::symbol::{Ident, Symbol};
|
||||
use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
|
||||
|
||||
/// Returns a set of mutated local variable IDs, or `None` if mutations could not be determined.
|
||||
|
@ -81,36 +79,6 @@ impl<'tcx> Delegate<'tcx> for MutVarsDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct UsedVisitor {
|
||||
pub var: Symbol, // var to look for
|
||||
pub used: bool, // has the var been used otherwise?
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for UsedVisitor {
|
||||
type Map = Map<'tcx>;
|
||||
|
||||
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
|
||||
if match_var(expr, self.var) {
|
||||
self.used = true;
|
||||
} else {
|
||||
walk_expr(self, expr);
|
||||
}
|
||||
}
|
||||
|
||||
fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
|
||||
NestedVisitorMap::None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_unused<'tcx>(ident: &'tcx Ident, body: &'tcx Expr<'_>) -> bool {
|
||||
let mut visitor = UsedVisitor {
|
||||
var: ident.name,
|
||||
used: false,
|
||||
};
|
||||
walk_expr(&mut visitor, body);
|
||||
!visitor.used
|
||||
}
|
||||
|
||||
pub struct ParamBindingIdCollector {
|
||||
binding_hir_ids: Vec<hir::HirId>,
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::utils::path_to_local_id;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::intravisit::{self, walk_expr, NestedVisitorMap, Visitor};
|
||||
use rustc_hir::{Arm, Expr, ExprKind, HirId, QPath, Stmt};
|
||||
use rustc_hir::{Arm, Body, Expr, HirId, Stmt};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::hir::map::Map;
|
||||
|
||||
|
@ -133,14 +133,16 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub struct LocalUsedVisitor {
|
||||
pub struct LocalUsedVisitor<'hir> {
|
||||
hir: Map<'hir>,
|
||||
pub local_hir_id: HirId,
|
||||
pub used: bool,
|
||||
}
|
||||
|
||||
impl LocalUsedVisitor {
|
||||
pub fn new(local_hir_id: HirId) -> Self {
|
||||
impl<'hir> LocalUsedVisitor<'hir> {
|
||||
pub fn new(cx: &LateContext<'hir>, local_hir_id: HirId) -> Self {
|
||||
Self {
|
||||
hir: cx.tcx.hir(),
|
||||
local_hir_id,
|
||||
used: false,
|
||||
}
|
||||
|
@ -151,35 +153,38 @@ impl LocalUsedVisitor {
|
|||
std::mem::replace(&mut self.used, false)
|
||||
}
|
||||
|
||||
pub fn check_arm(&mut self, arm: &Arm<'_>) -> bool {
|
||||
pub fn check_arm(&mut self, arm: &'hir Arm<'_>) -> bool {
|
||||
self.check(arm, Self::visit_arm)
|
||||
}
|
||||
|
||||
pub fn check_expr(&mut self, expr: &Expr<'_>) -> bool {
|
||||
pub fn check_body(&mut self, body: &'hir Body<'_>) -> bool {
|
||||
self.check(body, Self::visit_body)
|
||||
}
|
||||
|
||||
pub fn check_expr(&mut self, expr: &'hir Expr<'_>) -> bool {
|
||||
self.check(expr, Self::visit_expr)
|
||||
}
|
||||
|
||||
pub fn check_stmt(&mut self, stmt: &Stmt<'_>) -> bool {
|
||||
pub fn check_stmt(&mut self, stmt: &'hir Stmt<'_>) -> bool {
|
||||
self.check(stmt, Self::visit_stmt)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'v> Visitor<'v> for LocalUsedVisitor {
|
||||
impl<'v> Visitor<'v> for LocalUsedVisitor<'v> {
|
||||
type Map = Map<'v>;
|
||||
|
||||
fn visit_expr(&mut self, expr: &'v Expr<'v>) {
|
||||
if let ExprKind::Path(QPath::Resolved(None, path)) = expr.kind {
|
||||
if let Res::Local(id) = path.res {
|
||||
if id == self.local_hir_id {
|
||||
self.used = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if self.used {
|
||||
return;
|
||||
}
|
||||
if path_to_local_id(expr, self.local_hir_id) {
|
||||
self.used = true;
|
||||
} else {
|
||||
walk_expr(self, expr);
|
||||
}
|
||||
walk_expr(self, expr);
|
||||
}
|
||||
|
||||
fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
|
||||
NestedVisitorMap::None
|
||||
NestedVisitorMap::OnlyBodies(self.hir)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
|
|||
|
||||
// search for `for _ in vec![…]`
|
||||
if_chain! {
|
||||
if let Some((_, arg, _)) = higher::for_loop(expr);
|
||||
if let Some((_, arg, _, _)) = higher::for_loop(expr);
|
||||
if let Some(vec_args) = higher::vec_macro(cx, arg);
|
||||
if is_copy(cx, vec_type(cx.typeck_results().expr_ty_adjusted(arg)));
|
||||
then {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
clippy 0.1.51 (c6701036b 2021-01-23)
|
||||
clippy 0.1.51 (7f5bb7fd0 2021-02-06)
|
||||
|
||||
cargo-0.49.0//home/matthias/.rustup/toolchains/nightly-2021-01-15-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/macros/mod.rs:393:34 clippy::match_same_arms "this `match` has identical arm bodies"
|
||||
cargo-0.49.0//home/matthias/.rustup/toolchains/nightly-2021-02-03-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/macros/mod.rs:409:34 clippy::match_same_arms "this `match` has identical arm bodies"
|
||||
cargo-0.49.0/build.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.categories` metadata"
|
||||
cargo-0.49.0/build.rs:1:null clippy::cargo_common_metadata "package `cargo` is missing `package.keywords` metadata"
|
||||
cargo-0.49.0/src/bin/cargo/cli.rs:104:34 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`"
|
||||
|
@ -99,6 +99,7 @@ cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:411:9 clippy::
|
|||
cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:420:69 clippy::doc_markdown "you should put `mode/target_kind` between ticks in the documentation"
|
||||
cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:423:19 clippy::doc_markdown "you should put `CrateTypes` between ticks in the documentation"
|
||||
cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:424:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:424:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:469:58 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:603:19 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/core/compiler/build_context/target_info.rs:665:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
|
@ -111,6 +112,7 @@ cargo-0.49.0/src/cargo/core/compiler/build_plan.rs:4:9 clippy::doc_markdown "you
|
|||
cargo-0.49.0/src/cargo/core/compiler/build_plan.rs:5:66 clippy::doc_markdown "you should put `BuildPlan` between ticks in the documentation"
|
||||
cargo-0.49.0/src/cargo/core/compiler/build_plan.rs:66:40 clippy::ptr_arg "writing `&PathBuf` instead of `&Path` involves a new object where a slice will do."
|
||||
cargo-0.49.0/src/cargo/core/compiler/compilation.rs:150:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/compilation.rs:150:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/compilation.rs:169:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/compilation.rs:185:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/compilation.rs:193:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
|
@ -121,6 +123,7 @@ cargo-0.49.0/src/cargo/core/compiler/compilation.rs:91:5 clippy::missing_errors_
|
|||
cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:118:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:123:18 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison"
|
||||
cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:147:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:157:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:157:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:29:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/compiler/compile_kind.rs:33:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
|
@ -132,18 +135,23 @@ cargo-0.49.0/src/cargo/core/compiler/context/compilation_files.rs:324:66 clippy:
|
|||
cargo-0.49.0/src/cargo/core/compiler/context/compilation_files.rs:393:37 clippy::match_same_arms "this `match` has identical arm bodies"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/compilation_files.rs:426:71 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:125:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:125:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:125:5 clippy::too_many_lines "this function has too many lines (107/100)"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:270:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:286:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:308:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:308:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:340:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:340:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:349:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:349:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:354:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:358:21 clippy::doc_markdown "you should put `RunCustomBuild` between ticks in the documentation"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:361:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:374:43 clippy::doc_markdown "you should put `RunCustomBuild` between ticks in the documentation"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:378:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:383:41 clippy::doc_markdown "you should put `RunCustomBuild` between ticks in the documentation"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:384:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:384:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:391:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/compiler/context/mod.rs:397:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
|
@ -162,8 +170,10 @@ cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:353:56 clippy::manual_strip
|
|||
cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:448:27 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body"
|
||||
cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:464:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:481:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:481:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:48:56 clippy::doc_markdown "you should put `RunCustomBuild` between ticks in the documentation"
|
||||
cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:561:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:561:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:567:20 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:576:28 clippy::shadow_unrelated "`mut value` is being shadowed"
|
||||
cargo-0.49.0/src/cargo/core/compiler/custom_build.rs:606:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
|
@ -255,6 +265,7 @@ cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:134:1 clippy::missing_error
|
|||
cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:16:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:30:28 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:34:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/standard_lib.rs:34:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/compiler/timings.rs:16:1 clippy::struct_excessive_bools "more than 3 bools in a struct"
|
||||
cargo-0.49.0/src/cargo/core/compiler/timings.rs:192:64 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body"
|
||||
cargo-0.49.0/src/cargo/core/compiler/timings.rs:212:58 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body"
|
||||
|
@ -279,6 +290,7 @@ cargo-0.49.0/src/cargo/core/compiler/unit_graph.rs:65:1 clippy::missing_errors_d
|
|||
cargo-0.49.0/src/cargo/core/compiler/unit_graph.rs:65:1 clippy::module_name_repetitions "item name ends with its containing module's name"
|
||||
cargo-0.49.0/src/cargo/core/dependency.rs:157:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/dependency.rs:182:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/dependency.rs:203:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/dependency.rs:203:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/dependency.rs:224:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/dependency.rs:23:1 clippy::struct_excessive_bools "more than 3 bools in a struct"
|
||||
|
@ -288,10 +300,13 @@ cargo-0.49.0/src/cargo/core/dependency.rs:274:5 clippy::must_use_candidate "this
|
|||
cargo-0.49.0/src/cargo/core/dependency.rs:278:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/dependency.rs:287:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/dependency.rs:291:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/dependency.rs:296:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/dependency.rs:305:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/dependency.rs:311:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/dependency.rs:319:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/dependency.rs:323:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/dependency.rs:337:75 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/core/dependency.rs:379:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/dependency.rs:397:56 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/core/dependency.rs:403:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/dependency.rs:408:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
|
@ -419,6 +434,7 @@ cargo-0.49.0/src/cargo/core/package.rs:174:5 clippy::must_use_candidate "this me
|
|||
cargo-0.49.0/src/cargo/core/package.rs:182:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/package.rs:186:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/package.rs:190:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/package.rs:194:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/package.rs:194:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/package.rs:198:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/package.rs:202:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
|
@ -436,10 +452,12 @@ cargo-0.49.0/src/cargo/core/package.rs:287:1 clippy::module_name_repetitions "it
|
|||
cargo-0.49.0/src/cargo/core/package.rs:385:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/package.rs:421:5 clippy::needless_lifetimes "explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)"
|
||||
cargo-0.49.0/src/cargo/core/package.rs:425:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/package.rs:425:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/package.rs:452:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/package.rs:453:60 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/core/package.rs:459:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/package.rs:473:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/package.rs:552:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/package.rs:587:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/package.rs:588:9 clippy::needless_question_mark "Question mark operator is useless here"
|
||||
cargo-0.49.0/src/cargo/core/package.rs:682:46 clippy::cast_possible_truncation "casting `f64` to `u64` may truncate the value"
|
||||
|
@ -450,6 +468,7 @@ cargo-0.49.0/src/cargo/core/package.rs:731:5 clippy::missing_errors_doc "docs fo
|
|||
cargo-0.49.0/src/cargo/core/package.rs:790:13 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`"
|
||||
cargo-0.49.0/src/cargo/core/package.rs:988:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`"
|
||||
cargo-0.49.0/src/cargo/core/package_id.rs:115:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/package_id.rs:124:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/package_id.rs:124:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/package_id.rs:139:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/package_id.rs:142:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
|
@ -468,14 +487,17 @@ cargo-0.49.0/src/cargo/core/package_id_spec.rs:179:5 clippy::missing_errors_doc
|
|||
cargo-0.49.0/src/cargo/core/package_id_spec.rs:212:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope"
|
||||
cargo-0.49.0/src/cargo/core/package_id_spec.rs:231:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`"
|
||||
cargo-0.49.0/src/cargo/core/package_id_spec.rs:51:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/package_id_spec.rs:51:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/package_id_spec.rs:77:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/package_id_spec.rs:88:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/profiles.rs:1004:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/profiles.rs:1004:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/profiles.rs:1014:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/profiles.rs:1018:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/profiles.rs:1028:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/profiles.rs:106:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope"
|
||||
cargo-0.49.0/src/cargo/core/profiles.rs:143:5 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`"
|
||||
cargo-0.49.0/src/cargo/core/profiles.rs:286:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/profiles.rs:286:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/profiles.rs:294:40 clippy::if_not_else "unnecessary boolean `not` operation"
|
||||
cargo-0.49.0/src/cargo/core/profiles.rs:30:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
|
@ -483,6 +505,7 @@ cargo-0.49.0/src/cargo/core/profiles.rs:342:25 clippy::shadow_unrelated "`maker`
|
|||
cargo-0.49.0/src/cargo/core/profiles.rs:370:41 clippy::unused_self "unused `self` argument"
|
||||
cargo-0.49.0/src/cargo/core/profiles.rs:370:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/profiles.rs:372:9 clippy::field_reassign_with_default "field assignment outside of initializer for an instance created with Default::default()"
|
||||
cargo-0.49.0/src/cargo/core/profiles.rs:382:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/profiles.rs:382:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/profiles.rs:383:28 clippy::if_not_else "unnecessary boolean `not` operation"
|
||||
cargo-0.49.0/src/cargo/core/profiles.rs:397:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
|
@ -499,7 +522,9 @@ cargo-0.49.0/src/cargo/core/registry.rs:19:5 clippy::missing_errors_doc "docs fo
|
|||
cargo-0.49.0/src/cargo/core/registry.rs:240:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/registry.rs:26:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/registry.rs:344:49 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/core/registry.rs:358:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/registry.rs:369:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/registry.rs:424:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/registry.rs:424:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/registry.rs:49:1 clippy::module_name_repetitions "item name ends with its containing module's name"
|
||||
cargo-0.49.0/src/cargo/core/registry.rs:520:17 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`"
|
||||
|
@ -513,6 +538,7 @@ cargo-0.49.0/src/cargo/core/resolver/context.rs:274:53 clippy::redundant_closure
|
|||
cargo-0.49.0/src/cargo/core/resolver/context.rs:42:1 clippy::module_name_repetitions "item name starts with its containing module's name"
|
||||
cargo-0.49.0/src/cargo/core/resolver/context.rs:74:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/resolver/encode.rs:156:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/resolver/encode.rs:156:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/resolver/encode.rs:156:5 clippy::too_many_lines "this function has too many lines (164/100)"
|
||||
cargo-0.49.0/src/cargo/core/resolver/encode.rs:339:17 clippy::match_wildcard_for_single_variants "wildcard match will miss any future added variants"
|
||||
cargo-0.49.0/src/cargo/core/resolver/encode.rs:438:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope"
|
||||
|
@ -570,6 +596,7 @@ cargo-0.49.0/src/cargo/core/resolver/resolve.rs:255:5 clippy::must_use_candidate
|
|||
cargo-0.49.0/src/cargo/core/resolver/resolve.rs:259:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/resolver/resolve.rs:263:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/resolver/resolve.rs:269:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/resolver/resolve.rs:273:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/resolver/resolve.rs:273:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/resolver/resolve.rs:274:9 clippy::map_unwrap_or "called `map(<f>).unwrap_or_else(<g>)` on an `Option` value. This can be done more directly by calling `map_or_else(<g>, <f>)` instead"
|
||||
cargo-0.49.0/src/cargo/core/resolver/resolve.rs:280:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
|
@ -611,6 +638,7 @@ cargo-0.49.0/src/cargo/core/shell.rs:282:5 clippy::missing_errors_doc "docs for
|
|||
cargo-0.49.0/src/cargo/core/shell.rs:314:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/shell.rs:322:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/shell.rs:330:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/shell.rs:345:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/shell.rs:98:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/source/mod.rs:103:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/source/mod.rs:247:1 clippy::module_name_repetitions "item name starts with its containing module's name"
|
||||
|
@ -630,6 +658,7 @@ cargo-0.49.0/src/cargo/core/source/mod.rs:63:5 clippy::missing_errors_doc "docs
|
|||
cargo-0.49.0/src/cargo/core/source/mod.rs:74:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/source/mod.rs:83:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:107:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:107:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:128:50 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:147:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:156:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
|
@ -640,6 +669,7 @@ cargo-0.49.0/src/cargo/core/source/source_id.rs:171:19 clippy::doc_markdown "you
|
|||
cargo-0.49.0/src/cargo/core/source/source_id.rs:172:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:178:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:187:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:187:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:18:74 clippy::default_trait_access "calling `std::sync::Mutex::default()` is more clear than this expression"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:195:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:207:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
|
@ -652,10 +682,12 @@ cargo-0.49.0/src/cargo/core/source/source_id.rs:241:5 clippy::must_use_candidate
|
|||
cargo-0.49.0/src/cargo/core/source/source_id.rs:252:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:257:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:262:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:262:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:305:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:310:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:318:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:326:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:338:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:355:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:393:61 clippy::match_same_arms "this `match` has identical arm bodies"
|
||||
cargo-0.49.0/src/cargo/core/source/source_id.rs:394:42 clippy::match_same_arms "this `match` has identical arm bodies"
|
||||
|
@ -730,8 +762,10 @@ cargo-0.49.0/src/cargo/core/workspace.rs:150:5 clippy::missing_errors_doc "docs
|
|||
cargo-0.49.0/src/cargo/core/workspace.rs:159:16 clippy::redundant_else "redundant else block"
|
||||
cargo-0.49.0/src/cargo/core/workspace.rs:197:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/workspace.rs:225:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/workspace.rs:225:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/workspace.rs:255:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/workspace.rs:267:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/workspace.rs:317:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/workspace.rs:329:37 clippy::doc_markdown "you should put `VirtualManifest` between ticks in the documentation"
|
||||
cargo-0.49.0/src/cargo/core/workspace.rs:410:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/workspace.rs:440:9 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`"
|
||||
|
@ -742,9 +776,12 @@ cargo-0.49.0/src/cargo/core/workspace.rs:615:22 clippy::redundant_closure_for_me
|
|||
cargo-0.49.0/src/cargo/core/workspace.rs:762:27 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`"
|
||||
cargo-0.49.0/src/cargo/core/workspace.rs:784:17 clippy::if_not_else "unnecessary boolean `not` operation"
|
||||
cargo-0.49.0/src/cargo/core/workspace.rs:849:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/workspace.rs:849:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/core/workspace.rs:893:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/workspace.rs:906:24 clippy::redundant_else "redundant else block"
|
||||
cargo-0.49.0/src/cargo/core/workspace.rs:932:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/core/workspace.rs:932:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/lib.rs:177:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/lib.rs:177:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/lib.rs:180:36 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
|
@ -771,6 +808,7 @@ cargo-0.49.0/src/cargo/ops/cargo_compile.rs:249:1 clippy::missing_errors_doc "do
|
|||
cargo-0.49.0/src/cargo/ops/cargo_compile.rs:258:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_compile.rs:267:16 clippy::needless_question_mark "Question mark operator is useless here"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_compile.rs:275:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_compile.rs:275:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_compile.rs:275:1 clippy::too_many_lines "this function has too many lines (219/100)"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_compile.rs:468:9 clippy::default_trait_access "calling `std::collections::HashMap::default()` is more clear than this expression"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_compile.rs:548:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
|
@ -786,6 +824,7 @@ cargo-0.49.0/src/cargo/ops/cargo_compile.rs:612:21 clippy::doc_markdown "you sho
|
|||
cargo-0.49.0/src/cargo/ops/cargo_compile.rs:613:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_compile.rs:618:9 clippy::similar_names "binding's name is too similar to existing binding"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_compile.rs:641:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_compile.rs:652:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_compile.rs:652:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_compile.rs:655:50 clippy::match_same_arms "this `match` has identical arm bodies"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_compile.rs:673:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
|
@ -801,6 +840,7 @@ cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:160:5 clippy::items_after_
|
|||
cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:175:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:22:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:37:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:37:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_generate_lockfile.rs:37:1 clippy::too_many_lines "this function has too many lines (171/100)"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_install.rs:13:5 clippy::wildcard_imports "usage of wildcard import"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_install.rs:148:1 clippy::fn_params_excessive_bools "more than 3 bools in function parameters"
|
||||
|
@ -815,6 +855,7 @@ cargo-0.49.0/src/cargo/ops/cargo_install.rs:37:1 clippy::missing_errors_doc "doc
|
|||
cargo-0.49.0/src/cargo/ops/cargo_install.rs:454:22 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_install.rs:483:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_install.rs:683:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_install.rs:708:5 clippy::manual_flatten "unnecessary `if let` since only the `Some` variant of the iterator element is used"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_new.rs:101:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_new.rs:245:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_new.rs:251:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope"
|
||||
|
@ -843,6 +884,7 @@ cargo-0.49.0/src/cargo/ops/cargo_pkgid.rs:5:1 clippy::missing_errors_doc "docs f
|
|||
cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:14:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:171:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:37:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:37:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:57:49 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_read_manifest.rs:69:37 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_run.rs:25:24 clippy::if_not_else "unnecessary boolean `not` operation"
|
||||
|
@ -851,6 +893,7 @@ cargo-0.49.0/src/cargo/ops/cargo_run.rs:37:16 clippy::redundant_else "redundant
|
|||
cargo-0.49.0/src/cargo/ops/cargo_run.rs:53:9 clippy::if_not_else "unnecessary boolean `not` operation"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_run.rs:65:16 clippy::redundant_else "redundant else block"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_run.rs:9:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_run.rs:9:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_test.rs:16:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_test.rs:43:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/ops/cargo_test.rs:84:17 clippy::similar_names "binding's name is too similar to existing binding"
|
||||
|
@ -909,6 +952,7 @@ cargo-0.49.0/src/cargo/ops/registry.rs:505:38 clippy::default_trait_access "call
|
|||
cargo-0.49.0/src/cargo/ops/registry.rs:510:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/ops/registry.rs:529:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope"
|
||||
cargo-0.49.0/src/cargo/ops/registry.rs:53:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/ops/registry.rs:53:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/ops/registry.rs:573:22 clippy::match_same_arms "this `match` has identical arm bodies"
|
||||
cargo-0.49.0/src/cargo/ops/registry.rs:608:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/ops/registry.rs:621:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
|
@ -923,6 +967,7 @@ cargo-0.49.0/src/cargo/ops/registry.rs:794:16 clippy::single_match_else "you see
|
|||
cargo-0.49.0/src/cargo/ops/registry.rs:828:14 clippy::doc_markdown "you should put `SourceId` between ticks in the documentation"
|
||||
cargo-0.49.0/src/cargo/ops/registry.rs:848:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/ops/resolve.rs:199:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/ops/resolve.rs:199:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/ops/resolve.rs:199:1 clippy::module_name_repetitions "item name starts with its containing module's name"
|
||||
cargo-0.49.0/src/cargo/ops/resolve.rs:199:1 clippy::too_many_lines "this function has too many lines (137/100)"
|
||||
cargo-0.49.0/src/cargo/ops/resolve.rs:241:28 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`"
|
||||
|
@ -953,6 +998,7 @@ cargo-0.49.0/src/cargo/ops/tree/mod.rs:360:30 clippy::match_same_arms "this `mat
|
|||
cargo-0.49.0/src/cargo/ops/tree/mod.rs:58:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/ops/vendor.rs:14:1 clippy::module_name_repetitions "item name starts with its containing module's name"
|
||||
cargo-0.49.0/src/cargo/ops/vendor.rs:21:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/ops/vendor.rs:21:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/ops/vendor.rs:314:34 clippy::match_same_arms "this `match` has identical arm bodies"
|
||||
cargo-0.49.0/src/cargo/ops/vendor.rs:320:29 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison"
|
||||
cargo-0.49.0/src/cargo/ops/vendor.rs:320:60 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison"
|
||||
|
@ -971,8 +1017,10 @@ cargo-0.49.0/src/cargo/sources/directory.rs:14:1 clippy::module_name_repetitions
|
|||
cargo-0.49.0/src/cargo/sources/directory.rs:90:56 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/sources/git/source.rs:14:1 clippy::module_name_repetitions "item name ends with its containing module's name"
|
||||
cargo-0.49.0/src/cargo/sources/git/source.rs:25:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/sources/git/source.rs:25:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/sources/git/source.rs:49:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/sources/git/source.rs:53:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/sources/git/source.rs:53:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/sources/git/source.rs:69:20 clippy::comparison_to_empty "comparison to empty slice"
|
||||
cargo-0.49.0/src/cargo/sources/git/utils.rs:1025:19 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`"
|
||||
cargo-0.49.0/src/cargo/sources/git/utils.rs:1157:36 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison"
|
||||
|
@ -984,6 +1032,7 @@ cargo-0.49.0/src/cargo/sources/git/utils.rs:184:5 clippy::missing_errors_doc "do
|
|||
cargo-0.49.0/src/cargo/sources/git/utils.rs:188:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/sources/git/utils.rs:242:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/sources/git/utils.rs:253:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/sources/git/utils.rs:253:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/sources/git/utils.rs:262:13 clippy::if_not_else "unnecessary boolean `not` operation"
|
||||
cargo-0.49.0/src/cargo/sources/git/utils.rs:289:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/sources/git/utils.rs:294:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
|
@ -1013,6 +1062,7 @@ cargo-0.49.0/src/cargo/sources/path.rs:429:5 clippy::missing_errors_doc "docs fo
|
|||
cargo-0.49.0/src/cargo/sources/path.rs:460:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/sources/path.rs:473:43 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/sources/path.rs:482:43 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/sources/path.rs:55:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/sources/path.rs:63:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/sources/path.rs:77:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/sources/path.rs:98:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
|
@ -1046,6 +1096,7 @@ cargo-0.49.0/src/cargo/sources/registry/remote.rs:72:13 clippy::single_match_els
|
|||
cargo-0.49.0/src/cargo/sources/replaced.rs:12:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/sources/replaced.rs:5:1 clippy::module_name_repetitions "item name starts with its containing module's name"
|
||||
cargo-0.49.0/src/cargo/util/canonical_url.rs:19:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/canonical_url.rs:19:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/canonical_url.rs:50:41 clippy::case_sensitive_file_extension_comparisons "case-sensitive file extension comparison"
|
||||
cargo-0.49.0/src/cargo/util/canonical_url.rs:65:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/command_prelude.rs:218:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
|
@ -1091,6 +1142,7 @@ cargo-0.49.0/src/cargo/util/config/mod.rs:100:71 clippy::doc_markdown "you shoul
|
|||
cargo-0.49.0/src/cargo/util/config/mod.rs:1049:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:1064:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:1090:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:1090:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:1166:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:1179:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:1181:33 clippy::needless_question_mark "Question mark operator is useless here"
|
||||
|
@ -1105,6 +1157,7 @@ cargo-0.49.0/src/cargo/util/config/mod.rs:1225:5 clippy::missing_errors_doc "doc
|
|||
cargo-0.49.0/src/cargo/util/config/mod.rs:1229:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:124:1 clippy::struct_excessive_bools "more than 3 bools in a struct"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:1254:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:1263:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:1279:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:1281:9 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:1323:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope"
|
||||
|
@ -1120,6 +1173,7 @@ cargo-0.49.0/src/cargo/util/config/mod.rs:1588:5 clippy::must_use_candidate "thi
|
|||
cargo-0.49.0/src/cargo/util/config/mod.rs:1598:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:1619:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:1623:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:1623:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:1623:64 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:1649:9 clippy::option_if_let_else "use Option::map_or_else instead of an if let/else"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:1699:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope"
|
||||
|
@ -1151,14 +1205,13 @@ cargo-0.49.0/src/cargo/util/config/mod.rs:699:5 clippy::fn_params_excessive_bool
|
|||
cargo-0.49.0/src/cargo/util/config/mod.rs:699:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:719:58 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:816:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:875:36 clippy::similar_names "binding's name is too similar to existing binding"
|
||||
cargo-0.49.0/src/cargo/util/config/mod.rs:876:37 clippy::similar_names "binding's name is too similar to existing binding"
|
||||
cargo-0.49.0/src/cargo/util/config/path.rs:10:1 clippy::module_name_repetitions "item name ends with its containing module's name"
|
||||
cargo-0.49.0/src/cargo/util/config/path.rs:14:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/config/path.rs:48:1 clippy::module_name_repetitions "item name starts with its containing module's name"
|
||||
cargo-0.49.0/src/cargo/util/config/target.rs:12:1 clippy::module_name_repetitions "item name starts with its containing module's name"
|
||||
cargo-0.49.0/src/cargo/util/config/target.rs:24:1 clippy::module_name_repetitions "item name starts with its containing module's name"
|
||||
cargo-0.49.0/src/cargo/util/config/value.rs:29:1 clippy::module_name_repetitions "item name ends with its containing module's name"
|
||||
cargo-0.49.0/src/cargo/util/config/value.rs:70:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/config/value.rs:80:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/config/value.rs:81:9 clippy::match_like_matches_macro "match expression looks like `matches!` macro"
|
||||
cargo-0.49.0/src/cargo/util/cpu.rs:11:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
|
@ -1166,9 +1219,12 @@ cargo-0.49.0/src/cargo/util/cpu.rs:22:5 clippy::must_use_candidate "this method
|
|||
cargo-0.49.0/src/cargo/util/cpu.rs:82:25 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)"
|
||||
cargo-0.49.0/src/cargo/util/cpu.rs:82:9 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)"
|
||||
cargo-0.49.0/src/cargo/util/dependency_queue.rs:109:27 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/util/dependency_queue.rs:125:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/dependency_queue.rs:151:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/dependency_queue.rs:156:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/dependency_queue.rs:168:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/dependency_queue.rs:46:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/dependency_queue.rs:66:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/dependency_queue.rs:91:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope"
|
||||
cargo-0.49.0/src/cargo/util/diagnostic_server.rs:218:1 clippy::module_name_repetitions "item name ends with its containing module's name"
|
||||
cargo-0.49.0/src/cargo/util/diagnostic_server.rs:230:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
|
@ -1182,6 +1238,7 @@ cargo-0.49.0/src/cargo/util/errors.rs:143:5 clippy::must_use_candidate "this met
|
|||
cargo-0.49.0/src/cargo/util/errors.rs:150:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/errors.rs:15:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/errors.rs:237:5 clippy::pub_enum_variant_names "variant name ends with the enum's name"
|
||||
cargo-0.49.0/src/cargo/util/errors.rs:245:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/errors.rs:245:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/errors.rs:321:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/errors.rs:328:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
|
@ -1199,15 +1256,19 @@ cargo-0.49.0/src/cargo/util/flock.rs:150:5 clippy::missing_errors_doc "docs for
|
|||
cargo-0.49.0/src/cargo/util/flock.rs:156:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/flock.rs:170:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/flock.rs:192:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/flock.rs:29:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/flock.rs:29:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/flock.rs:321:5 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope"
|
||||
cargo-0.49.0/src/cargo/util/flock.rs:335:23 clippy::cast_possible_truncation "casting `i64` to `u32` may truncate the value"
|
||||
cargo-0.49.0/src/cargo/util/flock.rs:335:23 clippy::cast_sign_loss "casting `i64` to `u32` may lose the sign of the value"
|
||||
cargo-0.49.0/src/cargo/util/flock.rs:335:44 clippy::cast_possible_truncation "casting `i64` to `u32` may truncate the value"
|
||||
cargo-0.49.0/src/cargo/util/flock.rs:379:35 clippy::match_same_arms "this `match` has identical arm bodies"
|
||||
cargo-0.49.0/src/cargo/util/flock.rs:37:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/flock.rs:37:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/flock.rs:43:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/flock.rs:43:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/flock.rs:52:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/flock.rs:52:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/graph.rs:10:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/graph.rs:41:51 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/util/graph.rs:45:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
|
@ -1226,6 +1287,7 @@ cargo-0.49.0/src/cargo/util/hex.rs:8:9 clippy::cast_possible_truncation "casting
|
|||
cargo-0.49.0/src/cargo/util/hex.rs:9:9 clippy::cast_possible_truncation "casting `u64` to `u8` may truncate the value"
|
||||
cargo-0.49.0/src/cargo/util/important_paths.rs:23:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/important_paths.rs:6:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/interning.rs:66:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/interning.rs:66:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/interning.rs:77:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/into_url.rs:10:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
|
@ -1268,7 +1330,9 @@ cargo-0.49.0/src/cargo/util/paths.rs:415:1 clippy::missing_errors_doc "docs for
|
|||
cargo-0.49.0/src/cargo/util/paths.rs:445:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/paths.rs:459:45 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/util/paths.rs:469:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/paths.rs:469:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/paths.rs:54:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/paths.rs:61:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/paths.rs:61:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/paths.rs:63:19 clippy::option_if_let_else "use Option::map_or_else instead of an if let/else"
|
||||
cargo-0.49.0/src/cargo/util/paths.rs:88:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
|
@ -1281,6 +1345,7 @@ cargo-0.49.0/src/cargo/util/process_builder.rs:152:5 clippy::missing_errors_doc
|
|||
cargo-0.49.0/src/cargo/util/process_builder.rs:185:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/process_builder.rs:190:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/process_builder.rs:218:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/process_builder.rs:218:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/process_builder.rs:307:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/process_builder.rs:343:39 clippy::needless_pass_by_value "this argument is passed by value, but not consumed in the function body"
|
||||
cargo-0.49.0/src/cargo/util/progress.rs:122:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
|
@ -1300,16 +1365,22 @@ cargo-0.49.0/src/cargo/util/progress.rs:282:9 clippy::single_char_add_str "calli
|
|||
cargo-0.49.0/src/cargo/util/progress.rs:89:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/progress.rs:97:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/queue.rs:25:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/queue.rs:36:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/queue.rs:42:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/queue.rs:52:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/queue.rs:69:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/read2.rs:11:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/read2.rs:31:17 clippy::similar_names "binding's name is too similar to existing binding"
|
||||
cargo-0.49.0/src/cargo/util/restricted_names.rs:13:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/restricted_names.rs:26:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/restricted_names.rs:35:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/restricted_names.rs:45:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/restricted_names.rs:87:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/restricted_names.rs:87:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/restricted_names.rs:89:21 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/util/restricted_names.rs:8:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
cargo-0.49.0/src/cargo/util/rustc.rs:103:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/rustc.rs:103:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/rustc.rs:114:5 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link"
|
||||
cargo-0.49.0/src/cargo/util/rustc.rs:115:5 clippy::doc_markdown "you should put bare URLs between `<`/`>` or make a proper Markdown link"
|
||||
cargo-0.49.0/src/cargo/util/rustc.rs:162:17 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope"
|
||||
|
@ -1349,6 +1420,7 @@ cargo-0.49.0/src/cargo/util/toml/mod.rs:824:1 clippy::module_name_repetitions "i
|
|||
cargo-0.49.0/src/cargo/util/toml/mod.rs:834:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/toml/mod.rs:83:42 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
cargo-0.49.0/src/cargo/util/toml/mod.rs:852:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
cargo-0.49.0/src/cargo/util/toml/mod.rs:852:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
cargo-0.49.0/src/cargo/util/toml/mod.rs:852:5 clippy::too_many_lines "this function has too many lines (138/100)"
|
||||
cargo-0.49.0/src/cargo/util/toml/mod.rs:962:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope"
|
||||
cargo-0.49.0/src/cargo/util/toml/mod.rs:979:9 clippy::items_after_statements "adding items after statements is confusing, since items exist from the start of the scope"
|
||||
|
@ -1394,6 +1466,7 @@ iron-0.6.1/src/middleware/mod.rs:173:5 clippy::missing_errors_doc "docs for func
|
|||
iron-0.6.1/src/middleware/mod.rs:182:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
iron-0.6.1/src/middleware/mod.rs:192:1 clippy::module_name_repetitions "item name ends with its containing module's name"
|
||||
iron-0.6.1/src/middleware/mod.rs:217:25 clippy::doc_markdown "you should put `ChainBuilder` between ticks in the documentation"
|
||||
iron-0.6.1/src/middleware/mod.rs:264:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
iron-0.6.1/src/middleware/mod.rs:328:20 clippy::similar_names "binding's name is too similar to existing binding"
|
||||
iron-0.6.1/src/middleware/mod.rs:360:16 clippy::similar_names "binding's name is too similar to existing binding"
|
||||
iron-0.6.1/src/middleware/mod.rs:368:33 clippy::similar_names "binding's name is too similar to existing binding"
|
||||
|
@ -1424,8 +1497,11 @@ iron-0.6.1/src/request/url.rs:22:5 clippy::missing_errors_doc "docs for function
|
|||
iron-0.6.1/src/request/url.rs:31:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
iron-0.6.1/src/request/url.rs:47:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
iron-0.6.1/src/request/url.rs:52:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
iron-0.6.1/src/request/url.rs:57:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
iron-0.6.1/src/request/url.rs:57:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
iron-0.6.1/src/request/url.rs:63:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
iron-0.6.1/src/request/url.rs:63:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
iron-0.6.1/src/request/url.rs:73:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
iron-0.6.1/src/request/url.rs:73:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
iron-0.6.1/src/request/url.rs:83:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
iron-0.6.1/src/request/url.rs:96:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
|
@ -1915,6 +1991,7 @@ log-0.4.11/src/lib.rs:1118:5 clippy::must_use_candidate "this method could have
|
|||
log-0.4.11/src/lib.rs:1177:1 clippy::inline_always "you have declared `#[inline(always)]` on `max_level`. This is usually a bad idea"
|
||||
log-0.4.11/src/lib.rs:1178:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
log-0.4.11/src/lib.rs:1306:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
log-0.4.11/src/lib.rs:1306:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
log-0.4.11/src/lib.rs:1358:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
log-0.4.11/src/lib.rs:1359:5 clippy::if_not_else "unnecessary `!=` operation"
|
||||
log-0.4.11/src/lib.rs:1407:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
|
@ -1923,6 +2000,7 @@ log-0.4.11/src/lib.rs:356:1 clippy::expl_impl_clone_on_copy "you are implementin
|
|||
log-0.4.11/src/lib.rs:448:12 clippy::manual_range_contains "manual `RangeInclusive::contains` implementation"
|
||||
log-0.4.11/src/lib.rs:500:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
log-0.4.11/src/lib.rs:506:28 clippy::trivially_copy_pass_by_ref "this argument (8 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)"
|
||||
log-0.4.11/src/lib.rs:506:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
log-0.4.11/src/lib.rs:506:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
log-0.4.11/src/lib.rs:520:27 clippy::derive_hash_xor_eq "you are deriving `Hash` but have implemented `PartialEq` explicitly"
|
||||
log-0.4.11/src/lib.rs:538:1 clippy::expl_impl_clone_on_copy "you are implementing `Clone` explicitly on a `Copy` type"
|
||||
|
@ -2009,10 +2087,66 @@ proc-macro2-1.0.24/src/parse.rs:808:15 clippy::explicit_iter_loop "it is more co
|
|||
proc-macro2-1.0.24/src/wrapper.rs:415:24 clippy::trivially_copy_pass_by_ref "this argument (4 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)"
|
||||
proc-macro2-1.0.24/src/wrapper.rs:429:23 clippy::trivially_copy_pass_by_ref "this argument (4 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)"
|
||||
proc-macro2-1.0.24/src/wrapper.rs:492:17 clippy::trivially_copy_pass_by_ref "this argument (4 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)"
|
||||
puffin-02dd4a3/puffin-imgui/src/ui.rs:158:15 clippy::cast_precision_loss "casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)"
|
||||
puffin-02dd4a3/puffin-imgui/src/ui.rs:175:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
puffin-02dd4a3/puffin-imgui/src/ui.rs:183:5 clippy::too_many_lines "this function has too many lines (115/100)"
|
||||
puffin-02dd4a3/puffin-imgui/src/ui.rs:1:5 clippy::wildcard_imports "usage of wildcard import"
|
||||
puffin-02dd4a3/puffin-imgui/src/ui.rs:207:16 clippy::collapsible_else_if "this `else { if .. }` block can be collapsed"
|
||||
puffin-02dd4a3/puffin-imgui/src/ui.rs:271:67 clippy::cast_precision_loss "casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)"
|
||||
puffin-02dd4a3/puffin-imgui/src/ui.rs:2:5 clippy::wildcard_imports "usage of wildcard import"
|
||||
puffin-02dd4a3/puffin-imgui/src/ui.rs:376:29 clippy::cast_precision_loss "casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)"
|
||||
puffin-02dd4a3/puffin-imgui/src/ui.rs:381:44 clippy::cast_precision_loss "casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)"
|
||||
puffin-02dd4a3/puffin-imgui/src/ui.rs:453:9 clippy::similar_names "binding's name is too similar to existing binding"
|
||||
puffin-02dd4a3/puffin-imgui/src/ui.rs:540:14 clippy::cast_possible_truncation "casting `f64` to `f32` may truncate the value"
|
||||
puffin-02dd4a3/puffin-imgui/src/ui.rs:551:5 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)"
|
||||
puffin-02dd4a3/puffin-imgui/src/ui.rs:584:39 clippy::cast_precision_loss "casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide)"
|
||||
puffin-02dd4a3/puffin-imgui/src/ui.rs:59:26 clippy::unsafe_derive_deserialize "you are deriving `serde::Deserialize` on a type that has methods using `unsafe`"
|
||||
puffin-02dd4a3/puffin-imgui/src/ui.rs:61:1 clippy::module_name_repetitions "item name ends with its containing module's name"
|
||||
puffin-02dd4a3/puffin-imgui/src/ui.rs:627:39 clippy::cast_precision_loss "casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide)"
|
||||
puffin-02dd4a3/puffin-imgui/src/ui.rs:674:47 clippy::cast_precision_loss "casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)"
|
||||
puffin-02dd4a3/puffin-imgui/src/ui.rs:690:9 clippy::cast_precision_loss "casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide)"
|
||||
puffin-02dd4a3/puffin/src/data.rs:102:25 clippy::cast_possible_truncation "casting `usize` to `u8` may truncate the value"
|
||||
puffin-02dd4a3/puffin/src/data.rs:112:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
puffin-02dd4a3/puffin/src/data.rs:116:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
puffin-02dd4a3/puffin/src/data.rs:137:24 clippy::match_same_arms "this `match` has identical arm bodies"
|
||||
puffin-02dd4a3/puffin/src/data.rs:177:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
puffin-02dd4a3/puffin/src/data.rs:211:21 clippy::cast_possible_truncation "casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers"
|
||||
puffin-02dd4a3/puffin/src/data.rs:24:5 clippy::wildcard_imports "usage of wildcard import"
|
||||
puffin-02dd4a3/puffin/src/data.rs:75:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:113:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:147:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:147:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:165:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:200:21 clippy::default_trait_access "calling `Stream::default()` is more clear than this expression"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:257:78 clippy::default_trait_access "calling `std::cell::RefCell::default()` is more clear than this expression"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:297:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:302:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:308:28 clippy::default_trait_access "calling `FullProfileData::default()` is more clear than this expression"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:316:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:321:5 clippy::cast_possible_truncation "casting `u128` to `i64` may truncate the value"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:348:28 clippy::default_trait_access "calling `std::marker::PhantomData::default()` is more clear than this expression"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:359:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:375:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:376:5 clippy::option_if_let_else "use Option::map_or instead of an if let/else"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:377:9 clippy::option_if_let_else "use Option::map_or instead of an if let/else"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:406:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:408:5 clippy::option_if_let_else "use Option::map_or instead of an if let/else"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:69:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:73:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
puffin-02dd4a3/puffin/src/lib.rs:77:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
puffin-02dd4a3/puffin/src/merge.rs:21:1 clippy::module_name_repetitions "item name starts with its containing module's name"
|
||||
puffin-02dd4a3/puffin/src/merge.rs:28:1 clippy::module_name_repetitions "item name starts with its containing module's name"
|
||||
puffin-02dd4a3/puffin/src/merge.rs:28:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
puffin-02dd4a3/puffin/src/merge.rs:35:1 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
puffin-02dd4a3/puffin/src/merge.rs:35:1 clippy::module_name_repetitions "item name starts with its containing module's name"
|
||||
puffin-02dd4a3/puffin/src/merge.rs:64:43 clippy::default_trait_access "calling `std::vec::Vec::default()` is more clear than this expression"
|
||||
puffin-02dd4a3/puffin/src/merge.rs:65:54 clippy::default_trait_access "calling `std::collections::HashMap::default()` is more clear than this expression"
|
||||
puffin-02dd4a3/puffin/src/merge.rs:9:1 clippy::module_name_repetitions "item name starts with its containing module's name"
|
||||
quote-1.0.7/src/ext.rs:10:1 clippy::module_name_repetitions "item name ends with its containing module's name"
|
||||
quote-1.0.7/src/ext.rs:7:5 clippy::doc_markdown "you should put `TokenStream` between ticks in the documentation"
|
||||
quote-1.0.7/src/ident_fragment.rs:13:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
quote-1.0.7/src/ident_fragment.rs:51:31 clippy::manual_strip "stripping a prefix manually"
|
||||
quote-1.0.7/src/runtime.rs:332:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
quote-1.0.7/src/runtime.rs:52:5 clippy::module_name_repetitions "item name ends with its containing module's name"
|
||||
quote-1.0.7/src/runtime.rs:63:5 clippy::module_name_repetitions "item name ends with its containing module's name"
|
||||
quote-1.0.7/src/runtime.rs:66:33 clippy::doc_markdown "you should put `DoesNotHaveIter` between ticks in the documentation"
|
||||
|
@ -2049,6 +2183,7 @@ rand-0.7.3/src/distributions/binomial.rs:233:32 clippy::cast_precision_loss "cas
|
|||
rand-0.7.3/src/distributions/binomial.rs:234:27 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)"
|
||||
rand-0.7.3/src/distributions/binomial.rs:251:22 clippy::cast_sign_loss "casting `i64` to `u64` may lose the sign of the value"
|
||||
rand-0.7.3/src/distributions/binomial.rs:255:9 clippy::if_not_else "unnecessary `!=` operation"
|
||||
rand-0.7.3/src/distributions/binomial.rs:35:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
rand-0.7.3/src/distributions/binomial.rs:35:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
rand-0.7.3/src/distributions/binomial.rs:45:17 clippy::cast_precision_loss "casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)"
|
||||
rand-0.7.3/src/distributions/binomial.rs:46:5 clippy::cast_possible_truncation "casting `f64` to `i64` may truncate the value"
|
||||
|
@ -2059,18 +2194,25 @@ rand-0.7.3/src/distributions/binomial.rs:81:21 clippy::cast_precision_loss "cast
|
|||
rand-0.7.3/src/distributions/binomial.rs:82:32 clippy::cast_possible_truncation "casting `u64` to `i32` may truncate the value"
|
||||
rand-0.7.3/src/distributions/binomial.rs:88:26 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)"
|
||||
rand-0.7.3/src/distributions/binomial.rs:99:21 clippy::cast_precision_loss "casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)"
|
||||
rand-0.7.3/src/distributions/cauchy.rs:33:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
rand-0.7.3/src/distributions/cauchy.rs:33:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
rand-0.7.3/src/distributions/dirichlet.rs:52:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
rand-0.7.3/src/distributions/dirichlet.rs:64:32 clippy::unseparated_literal_suffix "float type suffix should be separated by an underscore"
|
||||
rand-0.7.3/src/distributions/dirichlet.rs:65:23 clippy::unseparated_literal_suffix "float type suffix should be separated by an underscore"
|
||||
rand-0.7.3/src/distributions/exponential.rs:76:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
rand-0.7.3/src/distributions/exponential.rs:76:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
rand-0.7.3/src/distributions/float.rs:73:1 clippy::module_name_repetitions "item name ends with its containing module's name"
|
||||
rand-0.7.3/src/distributions/gamma.rs:13:5 clippy::enum_glob_use "usage of wildcard import for enum variants"
|
||||
rand-0.7.3/src/distributions/gamma.rs:14:5 clippy::enum_glob_use "usage of wildcard import for enum variants"
|
||||
rand-0.7.3/src/distributions/gamma.rs:189:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
rand-0.7.3/src/distributions/gamma.rs:189:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
rand-0.7.3/src/distributions/gamma.rs:230:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
rand-0.7.3/src/distributions/gamma.rs:230:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
rand-0.7.3/src/distributions/gamma.rs:259:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
rand-0.7.3/src/distributions/gamma.rs:259:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
rand-0.7.3/src/distributions/gamma.rs:287:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
rand-0.7.3/src/distributions/gamma.rs:287:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
rand-0.7.3/src/distributions/gamma.rs:90:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
rand-0.7.3/src/distributions/gamma.rs:90:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
rand-0.7.3/src/distributions/integer.rs:23:9 clippy::cast_possible_truncation "casting `u32` to `u8` may truncate the value"
|
||||
rand-0.7.3/src/distributions/integer.rs:30:9 clippy::cast_possible_truncation "casting `u32` to `u16` may truncate the value"
|
||||
|
@ -2084,6 +2226,7 @@ rand-0.7.3/src/distributions/normal.rs:47:25 clippy::unseparated_literal_suffix
|
|||
rand-0.7.3/src/distributions/normal.rs:48:25 clippy::unseparated_literal_suffix "float type suffix should be separated by an underscore"
|
||||
rand-0.7.3/src/distributions/other.rs:89:9 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value"
|
||||
rand-0.7.3/src/distributions/pareto.rs:32:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
rand-0.7.3/src/distributions/poisson.rs:35:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
rand-0.7.3/src/distributions/poisson.rs:35:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
rand-0.7.3/src/distributions/poisson.rs:87:30 clippy::cast_possible_truncation "casting `f64` to `u64` may truncate the value"
|
||||
rand-0.7.3/src/distributions/poisson.rs:87:30 clippy::cast_sign_loss "casting `f64` to `u64` may lose the sign of the value"
|
||||
|
@ -2153,11 +2296,13 @@ rand-0.7.3/src/distributions/weighted/alias_method.rs:259:28 clippy::clone_on_co
|
|||
rand-0.7.3/src/distributions/weighted/alias_method.rs:296:9 clippy::map_clone "you are using an explicit closure for copying elements"
|
||||
rand-0.7.3/src/distributions/weighted/alias_method.rs:321:9 clippy::map_clone "you are using an explicit closure for copying elements"
|
||||
rand-0.7.3/src/distributions/weighted/alias_method.rs:78:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
rand-0.7.3/src/distributions/weighted/alias_method.rs:78:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
rand-0.7.3/src/distributions/weighted/alias_method.rs:78:5 clippy::too_many_lines "this function has too many lines (106/100)"
|
||||
rand-0.7.3/src/distributions/weighted/alias_method.rs:85:17 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers"
|
||||
rand-0.7.3/src/distributions/weighted/alias_method.rs:87:31 clippy::map_unwrap_or "called `map(<f>).unwrap_or(<a>)` on an `Option` value. This can be done more directly by calling `map_or(<a>, <f>)` instead"
|
||||
rand-0.7.3/src/distributions/weighted/mod.rs:100:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
rand-0.7.3/src/distributions/weighted/mod.rs:144:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
rand-0.7.3/src/distributions/weighted/mod.rs:144:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
rand-0.7.3/src/distributions/weighted/mod.rs:169:16 clippy::int_plus_one "unnecessary `>= y + 1` or `x - 1 >=`"
|
||||
rand-0.7.3/src/distributions/weighted/mod.rs:386:1 clippy::module_name_repetitions "item name starts with its containing module's name"
|
||||
rand-0.7.3/src/distributions/weighted/mod.rs:85:1 clippy::module_name_repetitions "item name starts with its containing module's name"
|
||||
|
@ -2188,6 +2333,7 @@ rand-0.7.3/src/rngs/std.rs:54:5 clippy::inline_always "you have declared `#[inli
|
|||
rand-0.7.3/src/rngs/std.rs:63:5 clippy::inline_always "you have declared `#[inline(always)]` on `from_seed`. This is usually a bad idea"
|
||||
rand-0.7.3/src/rngs/std.rs:68:5 clippy::inline_always "you have declared `#[inline(always)]` on `from_rng`. This is usually a bad idea"
|
||||
rand-0.7.3/src/rngs/thread.rs:57:1 clippy::module_name_repetitions "item name starts with its containing module's name"
|
||||
rand-0.7.3/src/rngs/thread.rs:80:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
rand-0.7.3/src/rngs/thread.rs:80:1 clippy::module_name_repetitions "item name starts with its containing module's name"
|
||||
rand-0.7.3/src/rngs/thread.rs:80:1 clippy::must_use_candidate "this function could have a `#[must_use]` attribute"
|
||||
rand-0.7.3/src/rngs/thread.rs:81:35 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
|
@ -2198,6 +2344,7 @@ rand-0.7.3/src/seq/index.rs:139:13 clippy::enum_glob_use "usage of wildcard impo
|
|||
rand-0.7.3/src/seq/index.rs:159:1 clippy::module_name_repetitions "item name starts with its containing module's name"
|
||||
rand-0.7.3/src/seq/index.rs:171:13 clippy::enum_glob_use "usage of wildcard import for enum variants"
|
||||
rand-0.7.3/src/seq/index.rs:180:13 clippy::enum_glob_use "usage of wildcard import for enum variants"
|
||||
rand-0.7.3/src/seq/index.rs:213:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
rand-0.7.3/src/seq/index.rs:223:18 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers"
|
||||
rand-0.7.3/src/seq/index.rs:224:18 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers"
|
||||
rand-0.7.3/src/seq/index.rs:233:25 clippy::cast_precision_loss "casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)"
|
||||
|
@ -2222,12 +2369,14 @@ rand-0.7.3/src/seq/mod.rs:45:4 clippy::needless_doctest_main "needless `fn main`
|
|||
rand-0.7.3/src/seq/mod.rs:527:26 clippy::cast_possible_truncation "casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers"
|
||||
rand_core-0.6.0/src/block.rs:117:1 clippy::module_name_repetitions "item name starts with its containing module's name"
|
||||
rand_core-0.6.0/src/block.rs:153:5 clippy::inline_always "you have declared `#[inline(always)]` on `index`. This is usually a bad idea"
|
||||
rand_core-0.6.0/src/block.rs:168:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
rand_core-0.6.0/src/block.rs:230:5 clippy::inline_always "you have declared `#[inline(always)]` on `try_fill_bytes`. This is usually a bad idea"
|
||||
rand_core-0.6.0/src/block.rs:240:5 clippy::inline_always "you have declared `#[inline(always)]` on `from_seed`. This is usually a bad idea"
|
||||
rand_core-0.6.0/src/block.rs:245:5 clippy::inline_always "you have declared `#[inline(always)]` on `seed_from_u64`. This is usually a bad idea"
|
||||
rand_core-0.6.0/src/block.rs:250:5 clippy::inline_always "you have declared `#[inline(always)]` on `from_rng`. This is usually a bad idea"
|
||||
rand_core-0.6.0/src/block.rs:280:1 clippy::module_name_repetitions "item name starts with its containing module's name"
|
||||
rand_core-0.6.0/src/block.rs:319:5 clippy::inline_always "you have declared `#[inline(always)]` on `index`. This is usually a bad idea"
|
||||
rand_core-0.6.0/src/block.rs:335:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
rand_core-0.6.0/src/block.rs:405:5 clippy::inline_always "you have declared `#[inline(always)]` on `try_fill_bytes`. This is usually a bad idea"
|
||||
rand_core-0.6.0/src/block.rs:415:5 clippy::inline_always "you have declared `#[inline(always)]` on `from_seed`. This is usually a bad idea"
|
||||
rand_core-0.6.0/src/block.rs:420:5 clippy::inline_always "you have declared `#[inline(always)]` on `seed_from_u64`. This is usually a bad idea"
|
||||
|
@ -2237,6 +2386,8 @@ rand_core-0.6.0/src/block.rs:68:1 clippy::module_name_repetitions "item name sta
|
|||
rand_core-0.6.0/src/error.rs:106:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
rand_core-0.6.0/src/error.rs:87:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
rand_core-0.6.0/src/error.rs:95:74 clippy::cast_possible_wrap "casting `u32` to `i32` may wrap around the value"
|
||||
rand_core-0.6.0/src/le.rs:18:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
rand_core-0.6.0/src/le.rs:27:1 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
rand_core-0.6.0/src/lib.rs:179:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
rand_core-0.6.0/src/lib.rs:301:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
rand_core-0.6.0/src/lib.rs:303:26 clippy::unreadable_literal "long literal lacking separators"
|
||||
|
@ -2548,6 +2699,7 @@ regex-1.3.2/src/compile.rs:1040:38 clippy::cast_possible_truncation "casting `u1
|
|||
regex-1.3.2/src/compile.rs:1051:25 clippy::unseparated_literal_suffix "integer type suffix should be separated by an underscore"
|
||||
regex-1.3.2/src/compile.rs:1071:8 clippy::cast_lossless "casting `u32` to `u64` may become silently lossy if you later change the type"
|
||||
regex-1.3.2/src/compile.rs:112:5 clippy::missing_errors_doc "docs for function returning `Result` missing `# Errors` section"
|
||||
regex-1.3.2/src/compile.rs:112:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
regex-1.3.2/src/compile.rs:154:30 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
regex-1.3.2/src/compile.rs:156:30 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
regex-1.3.2/src/compile.rs:185:5 clippy::unnecessary_wraps "this function's return value is unnecessarily wrapped by `Result`"
|
||||
|
@ -2877,6 +3029,7 @@ regex-1.3.2/src/re_bytes.rs:256:13 clippy::redundant_field_names "redundant fiel
|
|||
regex-1.3.2/src/re_bytes.rs:29:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
regex-1.3.2/src/re_bytes.rs:35:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
regex-1.3.2/src/re_bytes.rs:42:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
regex-1.3.2/src/re_bytes.rs:483:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
regex-1.3.2/src/re_bytes.rs:48:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
regex-1.3.2/src/re_bytes.rs:558:29 clippy::doc_markdown "you should put `shortest_match` between ticks in the documentation"
|
||||
regex-1.3.2/src/re_bytes.rs:55:33 clippy::redundant_field_names "redundant field names in struct initialization"
|
||||
|
@ -2917,6 +3070,7 @@ regex-1.3.2/src/re_unicode.rs:313:13 clippy::redundant_field_names "redundant fi
|
|||
regex-1.3.2/src/re_unicode.rs:38:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
regex-1.3.2/src/re_unicode.rs:44:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
regex-1.3.2/src/re_unicode.rs:51:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
regex-1.3.2/src/re_unicode.rs:533:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
regex-1.3.2/src/re_unicode.rs:57:5 clippy::must_use_candidate "this method could have a `#[must_use]` attribute"
|
||||
regex-1.3.2/src/re_unicode.rs:617:29 clippy::doc_markdown "you should put `shortest_match` between ticks in the documentation"
|
||||
regex-1.3.2/src/re_unicode.rs:631:29 clippy::doc_markdown "you should put `is_match` between ticks in the documentation"
|
||||
|
@ -2960,10 +3114,10 @@ regex-1.3.2/src/utf8.rs:85:19 clippy::cast_lossless "casting `u8` to `u32` may b
|
|||
regex-1.3.2/src/utf8.rs:92:23 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four"
|
||||
regex-1.3.2/src/utf8.rs:92:9 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four"
|
||||
regex-1.3.2/src/utf8.rs:97:16 clippy::unusual_byte_groupings "digits of hex or binary literal not grouped by four"
|
||||
ripgrep-12.1.1//home/matthias/.rustup/toolchains/nightly-2021-01-15-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/macros.rs:14:27 clippy::match_same_arms "this `match` has identical arm bodies"
|
||||
ripgrep-12.1.1//home/matthias/.rustup/toolchains/nightly-2021-01-15-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/macros.rs:14:27 clippy::match_same_arms "this `match` has identical arm bodies"
|
||||
ripgrep-12.1.1//home/matthias/.rustup/toolchains/nightly-2021-01-15-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/macros.rs:14:27 clippy::match_same_arms "this `match` has identical arm bodies"
|
||||
ripgrep-12.1.1//home/matthias/.rustup/toolchains/nightly-2021-01-15-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/macros.rs:14:27 clippy::match_same_arms "this `match` has identical arm bodies"
|
||||
ripgrep-12.1.1//home/matthias/.rustup/toolchains/nightly-2021-02-03-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:30:27 clippy::match_same_arms "this `match` has identical arm bodies"
|
||||
ripgrep-12.1.1//home/matthias/.rustup/toolchains/nightly-2021-02-03-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:30:27 clippy::match_same_arms "this `match` has identical arm bodies"
|
||||
ripgrep-12.1.1//home/matthias/.rustup/toolchains/nightly-2021-02-03-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:30:27 clippy::match_same_arms "this `match` has identical arm bodies"
|
||||
ripgrep-12.1.1//home/matthias/.rustup/toolchains/nightly-2021-02-03-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:30:27 clippy::match_same_arms "this `match` has identical arm bodies"
|
||||
ripgrep-12.1.1/build.rs:133:19 clippy::option_as_ref_deref "called `.as_ref().map(|x| &**x)` on an Option value. This can be done more directly by calling `githash.as_deref()` instead"
|
||||
ripgrep-12.1.1/build.rs:18:18 clippy::single_match_else "you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`"
|
||||
ripgrep-12.1.1/build.rs:225:14 clippy::redundant_closure_for_method_calls "redundant closure found"
|
||||
|
@ -3064,11 +3218,17 @@ ripgrep-12.1.1/crates/core/subject.rs:20:1 clippy::module_name_repetitions "item
|
|||
ripgrep-12.1.1/crates/core/subject.rs:4:1 clippy::single_component_path_imports "this import is redundant"
|
||||
syn-1.0.54/build.rs:1:null clippy::cargo_common_metadata "package `syn` is missing `package.keywords` metadata"
|
||||
syn-1.0.54/build.rs:1:null clippy::multiple_crate_versions "could not read cargo metadata: `cargo metadata` exited with an error: Downloading crates ...\n Downloaded syn-test-suite v0.0.0\nerror: failed to verify the checksum of `syn-test-suite v0.0.0`"
|
||||
syn-1.0.54/src/generics.rs:174:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
syn-1.0.54/src/lib.rs:1:null clippy::cargo_common_metadata "package `syn` is missing `package.keywords` metadata"
|
||||
syn-1.0.54/src/lib.rs:1:null clippy::multiple_crate_versions "could not read cargo metadata: `cargo metadata` exited with an error: Downloading crates ...\n Downloaded syn-test-suite v0.0.0\nerror: failed to verify the checksum of `syn-test-suite v0.0.0`"
|
||||
syn-1.0.54/src/lit.rs:1397:40 clippy::redundant_else "redundant else block"
|
||||
syn-1.0.54/src/lit.rs:1405:28 clippy::redundant_else "redundant else block"
|
||||
syn-1.0.54/src/lit.rs:1485:32 clippy::redundant_else "redundant else block"
|
||||
syn-1.0.54/src/lit.rs:343:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
syn-1.0.54/src/lit.rs:437:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
syn-1.0.54/src/lit.rs:916:9 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
syn-1.0.54/src/token.rs:974:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
syn-1.0.54/src/token.rs:996:5 clippy::missing_panics_doc "docs for function which may panic missing `# Panics` section"
|
||||
unicode-xid-0.2.1/src/lib.rs:1:null clippy::cargo_common_metadata "package `unicode-xid` is missing `package.categories` metadata"
|
||||
unicode-xid-0.2.1/src/lib.rs:56:11 clippy::upper_case_acronyms "name `UnicodeXID` contains a capitalized acronym"
|
||||
unicode-xid-0.2.1/src/lib.rs:57:64 clippy::doc_markdown "you should put `XID_Start` between ticks in the documentation"
|
||||
|
@ -3266,6 +3426,7 @@ clippy::explicit_deref_methods 1
|
|||
clippy::from_iter_instead_of_collect 1
|
||||
clippy::from_over_into 1
|
||||
clippy::int_plus_one 1
|
||||
clippy::manual_flatten 1
|
||||
clippy::manual_saturating_arithmetic 1
|
||||
clippy::mem_replace_with_default 1
|
||||
clippy::nonminimal_bool 1
|
||||
|
@ -3279,6 +3440,7 @@ clippy::should_implement_trait 1
|
|||
clippy::stable_sort_primitive 1
|
||||
clippy::unit_arg 1
|
||||
clippy::unnecessary_lazy_evaluations 1
|
||||
clippy::unsafe_derive_deserialize 1
|
||||
clippy::used_underscore_binding 1
|
||||
clippy::verbose_bit_mask 1
|
||||
clippy::while_let_on_iterator 1
|
||||
|
@ -3306,7 +3468,6 @@ clippy::ptr_arg 3
|
|||
clippy::zero_ptr 3
|
||||
clippy::let_underscore_drop 4
|
||||
clippy::too_many_arguments 4
|
||||
clippy::collapsible_else_if 5
|
||||
clippy::explicit_iter_loop 5
|
||||
clippy::field_reassign_with_default 5
|
||||
clippy::identity_op 5
|
||||
|
@ -3315,6 +3476,7 @@ clippy::match_like_matches_macro 5
|
|||
clippy::needless_return 5
|
||||
clippy::new_without_default 5
|
||||
clippy::ptr_as_ptr 5
|
||||
clippy::collapsible_else_if 6
|
||||
clippy::manual_strip 6
|
||||
clippy::non_ascii_literal 6
|
||||
clippy::single_component_path_imports 6
|
||||
|
@ -3332,12 +3494,11 @@ clippy::missing_safety_doc 10
|
|||
clippy::needless_doctest_main 10
|
||||
clippy::multiple_crate_versions 11
|
||||
clippy::needless_lifetimes 12
|
||||
clippy::option_if_let_else 12
|
||||
clippy::cargo_common_metadata 13
|
||||
clippy::shadow_unrelated 13
|
||||
clippy::linkedlist 14
|
||||
clippy::single_char_add_str 14
|
||||
clippy::default_trait_access 16
|
||||
clippy::option_if_let_else 15
|
||||
clippy::needless_pass_by_value 18
|
||||
clippy::upper_case_acronyms 18
|
||||
clippy::cast_possible_wrap 19
|
||||
|
@ -3348,25 +3509,27 @@ clippy::unusual_byte_groupings 19
|
|||
clippy::map_unwrap_or 20
|
||||
clippy::struct_excessive_bools 20
|
||||
clippy::redundant_static_lifetimes 21
|
||||
clippy::default_trait_access 22
|
||||
clippy::cast_lossless 23
|
||||
clippy::trivially_copy_pass_by_ref 26
|
||||
clippy::redundant_else 29
|
||||
clippy::too_many_lines 31
|
||||
clippy::cast_precision_loss 35
|
||||
clippy::too_many_lines 32
|
||||
clippy::if_not_else 35
|
||||
clippy::enum_glob_use 40
|
||||
clippy::unseparated_literal_suffix 41
|
||||
clippy::cast_precision_loss 44
|
||||
clippy::single_match_else 45
|
||||
clippy::inline_always 59
|
||||
clippy::match_same_arms 64
|
||||
clippy::similar_names 79
|
||||
clippy::cast_possible_truncation 91
|
||||
clippy::match_same_arms 65
|
||||
clippy::similar_names 78
|
||||
clippy::cast_possible_truncation 95
|
||||
clippy::missing_panics_doc 108
|
||||
clippy::redundant_field_names 111
|
||||
clippy::redundant_closure_for_method_calls 135
|
||||
clippy::module_name_repetitions 137
|
||||
clippy::items_after_statements 139
|
||||
clippy::wildcard_imports 160
|
||||
clippy::module_name_repetitions 142
|
||||
clippy::wildcard_imports 163
|
||||
clippy::doc_markdown 178
|
||||
clippy::missing_errors_doc 338
|
||||
clippy::missing_errors_doc 343
|
||||
clippy::unreadable_literal 365
|
||||
clippy::must_use_candidate 552
|
||||
clippy::must_use_candidate 565
|
|
@ -1,3 +1,3 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2021-02-03"
|
||||
components = ["llvm-tools-preview", "rustc-dev", "rust-src", "rustfmt"]
|
||||
channel = "nightly-2021-02-11"
|
||||
components = ["llvm-tools-preview", "rustc-dev", "rust-src"]
|
||||
|
|
26
src/main.rs
26
src/main.rs
|
@ -59,7 +59,6 @@ pub fn main() {
|
|||
}
|
||||
|
||||
struct ClippyCmd {
|
||||
unstable_options: bool,
|
||||
cargo_subcommand: &'static str,
|
||||
args: Vec<String>,
|
||||
clippy_args: Vec<String>,
|
||||
|
@ -105,21 +104,12 @@ impl ClippyCmd {
|
|||
}
|
||||
|
||||
ClippyCmd {
|
||||
unstable_options,
|
||||
cargo_subcommand,
|
||||
args,
|
||||
clippy_args,
|
||||
}
|
||||
}
|
||||
|
||||
fn path_env(&self) -> &'static str {
|
||||
if self.unstable_options {
|
||||
"RUSTC_WORKSPACE_WRAPPER"
|
||||
} else {
|
||||
"RUSTC_WRAPPER"
|
||||
}
|
||||
}
|
||||
|
||||
fn path() -> PathBuf {
|
||||
let mut path = env::current_exe()
|
||||
.expect("current executable path invalid")
|
||||
|
@ -156,7 +146,7 @@ impl ClippyCmd {
|
|||
.map(|arg| format!("{}__CLIPPY_HACKERY__", arg))
|
||||
.collect();
|
||||
|
||||
cmd.env(self.path_env(), Self::path())
|
||||
cmd.env("RUSTC_WORKSPACE_WRAPPER", Self::path())
|
||||
.envs(ClippyCmd::target_dir())
|
||||
.env("CLIPPY_ARGS", clippy_args)
|
||||
.arg(self.cargo_subcommand)
|
||||
|
@ -195,7 +185,7 @@ mod tests {
|
|||
#[should_panic]
|
||||
fn fix_without_unstable() {
|
||||
let args = "cargo clippy --fix".split_whitespace().map(ToString::to_string);
|
||||
let _ = ClippyCmd::new(args);
|
||||
ClippyCmd::new(args);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -205,7 +195,6 @@ mod tests {
|
|||
.map(ToString::to_string);
|
||||
let cmd = ClippyCmd::new(args);
|
||||
assert_eq!("fix", cmd.cargo_subcommand);
|
||||
assert_eq!("RUSTC_WORKSPACE_WRAPPER", cmd.path_env());
|
||||
assert!(cmd.args.iter().any(|arg| arg.ends_with("unstable-options")));
|
||||
}
|
||||
|
||||
|
@ -232,16 +221,5 @@ mod tests {
|
|||
let args = "cargo clippy".split_whitespace().map(ToString::to_string);
|
||||
let cmd = ClippyCmd::new(args);
|
||||
assert_eq!("check", cmd.cargo_subcommand);
|
||||
assert_eq!("RUSTC_WRAPPER", cmd.path_env());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_unstable() {
|
||||
let args = "cargo clippy -Zunstable-options"
|
||||
.split_whitespace()
|
||||
.map(ToString::to_string);
|
||||
let cmd = ClippyCmd::new(args);
|
||||
assert_eq!("check", cmd.cargo_subcommand);
|
||||
assert_eq!("RUSTC_WORKSPACE_WRAPPER", cmd.path_env());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -214,6 +214,7 @@ fn run_ui_cargo(config: &mut compiletest::Config) {
|
|||
Some("main.rs") => {},
|
||||
_ => continue,
|
||||
}
|
||||
set_var("CLIPPY_CONF_DIR", case.path());
|
||||
let paths = compiletest::common::TestPaths {
|
||||
file: file_path,
|
||||
base: config.src_base.clone(),
|
||||
|
@ -241,9 +242,11 @@ fn run_ui_cargo(config: &mut compiletest::Config) {
|
|||
let tests = compiletest::make_tests(&config);
|
||||
|
||||
let current_dir = env::current_dir().unwrap();
|
||||
let conf_dir = var("CLIPPY_CONF_DIR").unwrap_or_default();
|
||||
let filter = env::var("TESTNAME").ok();
|
||||
let res = run_tests(&config, &filter, tests);
|
||||
env::set_current_dir(current_dir).unwrap();
|
||||
set_var("CLIPPY_CONF_DIR", conf_dir);
|
||||
|
||||
match res {
|
||||
Ok(true) => {},
|
||||
|
|
1
tests/ui-cargo/cargo_common_metadata/fail/clippy.toml
Normal file
1
tests/ui-cargo/cargo_common_metadata/fail/clippy.toml
Normal file
|
@ -0,0 +1 @@
|
|||
cargo-ignore-publish = true
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "cargo_common_metadata"
|
||||
version = "0.1.0"
|
||||
publish = ["some-registry-name"]
|
||||
|
||||
[workspace]
|
|
@ -0,0 +1,4 @@
|
|||
// compile-flags: --crate-name=cargo_common_metadata
|
||||
#![warn(clippy::cargo_common_metadata)]
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,18 @@
|
|||
error: package `cargo_common_metadata` is missing `package.authors` metadata
|
||||
|
|
||||
= note: `-D clippy::cargo-common-metadata` implied by `-D warnings`
|
||||
|
||||
error: package `cargo_common_metadata` is missing `package.description` metadata
|
||||
|
||||
error: package `cargo_common_metadata` is missing `either package.license or package.license_file` metadata
|
||||
|
||||
error: package `cargo_common_metadata` is missing `package.repository` metadata
|
||||
|
||||
error: package `cargo_common_metadata` is missing `package.readme` metadata
|
||||
|
||||
error: package `cargo_common_metadata` is missing `package.keywords` metadata
|
||||
|
||||
error: package `cargo_common_metadata` is missing `package.categories` metadata
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "cargo_common_metadata"
|
||||
version = "0.1.0"
|
||||
publish = true
|
||||
|
||||
[workspace]
|
|
@ -0,0 +1,4 @@
|
|||
// compile-flags: --crate-name=cargo_common_metadata
|
||||
#![warn(clippy::cargo_common_metadata)]
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,18 @@
|
|||
error: package `cargo_common_metadata` is missing `package.authors` metadata
|
||||
|
|
||||
= note: `-D clippy::cargo-common-metadata` implied by `-D warnings`
|
||||
|
||||
error: package `cargo_common_metadata` is missing `package.description` metadata
|
||||
|
||||
error: package `cargo_common_metadata` is missing `either package.license or package.license_file` metadata
|
||||
|
||||
error: package `cargo_common_metadata` is missing `package.repository` metadata
|
||||
|
||||
error: package `cargo_common_metadata` is missing `package.readme` metadata
|
||||
|
||||
error: package `cargo_common_metadata` is missing `package.keywords` metadata
|
||||
|
||||
error: package `cargo_common_metadata` is missing `package.categories` metadata
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
1
tests/ui-cargo/cargo_common_metadata/pass/clippy.toml
Normal file
1
tests/ui-cargo/cargo_common_metadata/pass/clippy.toml
Normal file
|
@ -0,0 +1 @@
|
|||
cargo-ignore-publish = true
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "cargo_common_metadata"
|
||||
version = "0.1.0"
|
||||
publish = []
|
||||
|
||||
[workspace]
|
|
@ -0,0 +1,4 @@
|
|||
// compile-flags: --crate-name=cargo_common_metadata
|
||||
#![warn(clippy::cargo_common_metadata)]
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "cargo_common_metadata"
|
||||
version = "0.1.0"
|
||||
publish = false
|
||||
|
||||
[workspace]
|
|
@ -0,0 +1,4 @@
|
|||
// compile-flags: --crate-name=cargo_common_metadata
|
||||
#![warn(clippy::cargo_common_metadata)]
|
||||
|
||||
fn main() {}
|
|
@ -1 +1 @@
|
|||
disallowed-methods = ["core::iter::traits::iterator::Iterator::sum", "regex::re_unicode::Regex::is_match"]
|
||||
disallowed-methods = ["core::iter::traits::iterator::Iterator::sum", "regex::re_unicode::Regex::is_match", "regex::re_unicode::Regex::new"]
|
||||
|
|
|
@ -4,10 +4,9 @@ extern crate regex;
|
|||
use regex::Regex;
|
||||
|
||||
fn main() {
|
||||
let a = vec![1, 2, 3, 4];
|
||||
let re = Regex::new(r"ab.*c").unwrap();
|
||||
|
||||
re.is_match("abc");
|
||||
|
||||
let a = vec![1, 2, 3, 4];
|
||||
a.iter().sum::<i32>();
|
||||
}
|
||||
|
|
|
@ -1,16 +1,22 @@
|
|||
error: use of a disallowed method `regex::re_unicode::Regex::is_match`
|
||||
--> $DIR/conf_disallowed_method.rs:10:5
|
||||
error: use of a disallowed method `regex::re_unicode::Regex::new`
|
||||
--> $DIR/conf_disallowed_method.rs:7:14
|
||||
|
|
||||
LL | re.is_match("abc");
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
LL | let re = Regex::new(r"ab.*c").unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::disallowed-method` implied by `-D warnings`
|
||||
|
||||
error: use of a disallowed method `regex::re_unicode::Regex::is_match`
|
||||
--> $DIR/conf_disallowed_method.rs:8:5
|
||||
|
|
||||
LL | re.is_match("abc");
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: use of a disallowed method `core::iter::traits::iterator::Iterator::sum`
|
||||
--> $DIR/conf_disallowed_method.rs:12:5
|
||||
--> $DIR/conf_disallowed_method.rs:11:5
|
||||
|
|
||||
LL | a.iter().sum::<i32>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `msrv`, `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `pass-by-value-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `disallowed-methods`, `unreadable-literal-lint-fractions`, `third-party` at line 5 column 1
|
||||
error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `msrv`, `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `pass-by-value-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `disallowed-methods`, `unreadable-literal-lint-fractions`, `cargo-ignore-publish`, `third-party` at line 5 column 1
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
11
tests/ui/bytes_nth.fixed
Normal file
11
tests/ui/bytes_nth.fixed
Normal file
|
@ -0,0 +1,11 @@
|
|||
// run-rustfix
|
||||
|
||||
#![allow(clippy::unnecessary_operation)]
|
||||
#![warn(clippy::bytes_nth)]
|
||||
|
||||
fn main() {
|
||||
let s = String::from("String");
|
||||
s.as_bytes().get(3);
|
||||
&s.as_bytes().get(3);
|
||||
s[..].as_bytes().get(3);
|
||||
}
|
11
tests/ui/bytes_nth.rs
Normal file
11
tests/ui/bytes_nth.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// run-rustfix
|
||||
|
||||
#![allow(clippy::unnecessary_operation)]
|
||||
#![warn(clippy::bytes_nth)]
|
||||
|
||||
fn main() {
|
||||
let s = String::from("String");
|
||||
s.bytes().nth(3);
|
||||
&s.bytes().nth(3);
|
||||
s[..].bytes().nth(3);
|
||||
}
|
22
tests/ui/bytes_nth.stderr
Normal file
22
tests/ui/bytes_nth.stderr
Normal file
|
@ -0,0 +1,22 @@
|
|||
error: called `.byte().nth()` on a `String`
|
||||
--> $DIR/bytes_nth.rs:8:5
|
||||
|
|
||||
LL | s.bytes().nth(3);
|
||||
| ^^^^^^^^^^^^^^^^ help: try: `s.as_bytes().get(3)`
|
||||
|
|
||||
= note: `-D clippy::bytes-nth` implied by `-D warnings`
|
||||
|
||||
error: called `.byte().nth()` on a `String`
|
||||
--> $DIR/bytes_nth.rs:9:6
|
||||
|
|
||||
LL | &s.bytes().nth(3);
|
||||
| ^^^^^^^^^^^^^^^^ help: try: `s.as_bytes().get(3)`
|
||||
|
||||
error: called `.byte().nth()` on a `str`
|
||||
--> $DIR/bytes_nth.rs:10:5
|
||||
|
|
||||
LL | s[..].bytes().nth(3);
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: try: `s[..].as_bytes().get(3)`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
|
@ -224,6 +224,14 @@ fn negative_cases(res_opt: Result<Option<u32>, String>, res_res: Result<Result<u
|
|||
},
|
||||
_ => return,
|
||||
}
|
||||
if let Ok(val) = res_opt {
|
||||
if let Some(n) = val {
|
||||
let _ = || {
|
||||
// usage in closure
|
||||
println!("{:?}", val);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn make<T>() -> T {
|
||||
|
|
16
tests/ui/filter_map_identity.fixed
Normal file
16
tests/ui/filter_map_identity.fixed
Normal file
|
@ -0,0 +1,16 @@
|
|||
// run-rustfix
|
||||
|
||||
#![allow(unused_imports)]
|
||||
#![warn(clippy::filter_map_identity)]
|
||||
|
||||
fn main() {
|
||||
let iterator = vec![Some(1), None, Some(2)].into_iter();
|
||||
let _ = iterator.flatten();
|
||||
|
||||
let iterator = vec![Some(1), None, Some(2)].into_iter();
|
||||
let _ = iterator.flatten();
|
||||
|
||||
use std::convert::identity;
|
||||
let iterator = vec![Some(1), None, Some(2)].into_iter();
|
||||
let _ = iterator.flatten();
|
||||
}
|
16
tests/ui/filter_map_identity.rs
Normal file
16
tests/ui/filter_map_identity.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
// run-rustfix
|
||||
|
||||
#![allow(unused_imports)]
|
||||
#![warn(clippy::filter_map_identity)]
|
||||
|
||||
fn main() {
|
||||
let iterator = vec![Some(1), None, Some(2)].into_iter();
|
||||
let _ = iterator.filter_map(|x| x);
|
||||
|
||||
let iterator = vec![Some(1), None, Some(2)].into_iter();
|
||||
let _ = iterator.filter_map(std::convert::identity);
|
||||
|
||||
use std::convert::identity;
|
||||
let iterator = vec![Some(1), None, Some(2)].into_iter();
|
||||
let _ = iterator.filter_map(identity);
|
||||
}
|
22
tests/ui/filter_map_identity.stderr
Normal file
22
tests/ui/filter_map_identity.stderr
Normal file
|
@ -0,0 +1,22 @@
|
|||
error: called `filter_map(|x| x)` on an `Iterator`
|
||||
--> $DIR/filter_map_identity.rs:8:22
|
||||
|
|
||||
LL | let _ = iterator.filter_map(|x| x);
|
||||
| ^^^^^^^^^^^^^^^^^ help: try: `flatten()`
|
||||
|
|
||||
= note: `-D clippy::filter-map-identity` implied by `-D warnings`
|
||||
|
||||
error: called `filter_map(std::convert::identity)` on an `Iterator`
|
||||
--> $DIR/filter_map_identity.rs:11:22
|
||||
|
|
||||
LL | let _ = iterator.filter_map(std::convert::identity);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
|
||||
|
||||
error: called `filter_map(std::convert::identity)` on an `Iterator`
|
||||
--> $DIR/filter_map_identity.rs:15:22
|
||||
|
|
||||
LL | let _ = iterator.filter_map(identity);
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
error: called `flat_map(|x| x)` on an `Iterator`
|
||||
--> $DIR/unnecessary_flat_map.rs:10:22
|
||||
--> $DIR/flat_map_identity.rs:10:22
|
||||
|
|
||||
LL | let _ = iterator.flat_map(|x| x);
|
||||
| ^^^^^^^^^^^^^^^ help: try: `flatten()`
|
||||
|
@ -7,7 +7,7 @@ LL | let _ = iterator.flat_map(|x| x);
|
|||
= note: `-D clippy::flat-map-identity` implied by `-D warnings`
|
||||
|
||||
error: called `flat_map(std::convert::identity)` on an `Iterator`
|
||||
--> $DIR/unnecessary_flat_map.rs:13:22
|
||||
--> $DIR/flat_map_identity.rs:13:22
|
||||
|
|
||||
LL | let _ = iterator.flat_map(convert::identity);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
|
48
tests/ui/from_iter_instead_of_collect.fixed
Normal file
48
tests/ui/from_iter_instead_of_collect.fixed
Normal file
|
@ -0,0 +1,48 @@
|
|||
// run-rustfix
|
||||
|
||||
#![warn(clippy::from_iter_instead_of_collect)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque};
|
||||
use std::iter::FromIterator;
|
||||
|
||||
fn main() {
|
||||
let iter_expr = std::iter::repeat(5).take(5);
|
||||
let _ = iter_expr.collect::<Vec<_>>();
|
||||
|
||||
let _ = vec![5, 5, 5, 5].iter().enumerate().collect::<HashMap<usize, &i8>>();
|
||||
|
||||
Vec::from_iter(vec![42u32]);
|
||||
|
||||
let a = vec![0, 1, 2];
|
||||
assert_eq!(a, (0..3).collect::<Vec<_>>());
|
||||
assert_eq!(a, (0..3).collect::<Vec<i32>>());
|
||||
|
||||
let mut b = (0..3).collect::<VecDeque<_>>();
|
||||
b.push_back(4);
|
||||
|
||||
let mut b = (0..3).collect::<VecDeque<i32>>();
|
||||
b.push_back(4);
|
||||
|
||||
{
|
||||
use std::collections;
|
||||
let mut b = (0..3).collect::<collections::VecDeque<i32>>();
|
||||
b.push_back(4);
|
||||
}
|
||||
|
||||
let values = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')];
|
||||
let bm = values.iter().cloned().collect::<BTreeMap<_, _>>();
|
||||
let mut bar = bm.range(0..2).collect::<BTreeMap<_, _>>();
|
||||
bar.insert(&4, &'e');
|
||||
|
||||
let mut bts = (0..3).collect::<BTreeSet<_>>();
|
||||
bts.insert(2);
|
||||
{
|
||||
use std::collections;
|
||||
let _ = (0..3).collect::<collections::BTreeSet<_>>();
|
||||
let _ = (0..3).collect::<collections::BTreeSet<u32>>();
|
||||
}
|
||||
|
||||
for _i in [1, 2, 3].iter().collect::<Vec<_>>() {}
|
||||
for _i in [1, 2, 3].iter().collect::<Vec<&i32>>() {}
|
||||
}
|
|
@ -1,13 +1,48 @@
|
|||
#![warn(clippy::from_iter_instead_of_collect)]
|
||||
// run-rustfix
|
||||
|
||||
use std::collections::HashMap;
|
||||
#![warn(clippy::from_iter_instead_of_collect)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque};
|
||||
use std::iter::FromIterator;
|
||||
|
||||
fn main() {
|
||||
let iter_expr = std::iter::repeat(5).take(5);
|
||||
Vec::from_iter(iter_expr);
|
||||
let _ = Vec::from_iter(iter_expr);
|
||||
|
||||
HashMap::<usize, &i8>::from_iter(vec![5, 5, 5, 5].iter().enumerate());
|
||||
let _ = HashMap::<usize, &i8>::from_iter(vec![5, 5, 5, 5].iter().enumerate());
|
||||
|
||||
Vec::from_iter(vec![42u32]);
|
||||
|
||||
let a = vec![0, 1, 2];
|
||||
assert_eq!(a, Vec::from_iter(0..3));
|
||||
assert_eq!(a, Vec::<i32>::from_iter(0..3));
|
||||
|
||||
let mut b = VecDeque::from_iter(0..3);
|
||||
b.push_back(4);
|
||||
|
||||
let mut b = VecDeque::<i32>::from_iter(0..3);
|
||||
b.push_back(4);
|
||||
|
||||
{
|
||||
use std::collections;
|
||||
let mut b = collections::VecDeque::<i32>::from_iter(0..3);
|
||||
b.push_back(4);
|
||||
}
|
||||
|
||||
let values = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')];
|
||||
let bm = BTreeMap::from_iter(values.iter().cloned());
|
||||
let mut bar = BTreeMap::from_iter(bm.range(0..2));
|
||||
bar.insert(&4, &'e');
|
||||
|
||||
let mut bts = BTreeSet::from_iter(0..3);
|
||||
bts.insert(2);
|
||||
{
|
||||
use std::collections;
|
||||
let _ = collections::BTreeSet::from_iter(0..3);
|
||||
let _ = collections::BTreeSet::<u32>::from_iter(0..3);
|
||||
}
|
||||
|
||||
for _i in Vec::from_iter([1, 2, 3].iter()) {}
|
||||
for _i in Vec::<&i32>::from_iter([1, 2, 3].iter()) {}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,88 @@
|
|||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:8:5
|
||||
--> $DIR/from_iter_instead_of_collect.rs:11:13
|
||||
|
|
||||
LL | Vec::from_iter(iter_expr);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter_expr.collect()`
|
||||
LL | let _ = Vec::from_iter(iter_expr);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter_expr.collect::<Vec<_>>()`
|
||||
|
|
||||
= note: `-D clippy::from-iter-instead-of-collect` implied by `-D warnings`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:10:5
|
||||
--> $DIR/from_iter_instead_of_collect.rs:13:13
|
||||
|
|
||||
LL | HashMap::<usize, &i8>::from_iter(vec![5, 5, 5, 5].iter().enumerate());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `vec![5, 5, 5, 5].iter().enumerate().collect()`
|
||||
LL | let _ = HashMap::<usize, &i8>::from_iter(vec![5, 5, 5, 5].iter().enumerate());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `vec![5, 5, 5, 5].iter().enumerate().collect::<HashMap<usize, &i8>>()`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:18:19
|
||||
|
|
||||
LL | assert_eq!(a, Vec::from_iter(0..3));
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<Vec<_>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:19:19
|
||||
|
|
||||
LL | assert_eq!(a, Vec::<i32>::from_iter(0..3));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<Vec<i32>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:21:17
|
||||
|
|
||||
LL | let mut b = VecDeque::from_iter(0..3);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<VecDeque<_>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:24:17
|
||||
|
|
||||
LL | let mut b = VecDeque::<i32>::from_iter(0..3);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<VecDeque<i32>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:29:21
|
||||
|
|
||||
LL | let mut b = collections::VecDeque::<i32>::from_iter(0..3);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<collections::VecDeque<i32>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:34:14
|
||||
|
|
||||
LL | let bm = BTreeMap::from_iter(values.iter().cloned());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `values.iter().cloned().collect::<BTreeMap<_, _>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:35:19
|
||||
|
|
||||
LL | let mut bar = BTreeMap::from_iter(bm.range(0..2));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `bm.range(0..2).collect::<BTreeMap<_, _>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:38:19
|
||||
|
|
||||
LL | let mut bts = BTreeSet::from_iter(0..3);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<BTreeSet<_>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:42:17
|
||||
|
|
||||
LL | let _ = collections::BTreeSet::from_iter(0..3);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<collections::BTreeSet<_>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:43:17
|
||||
|
|
||||
LL | let _ = collections::BTreeSet::<u32>::from_iter(0..3);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<collections::BTreeSet<u32>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:46:15
|
||||
|
|
||||
LL | for _i in Vec::from_iter([1, 2, 3].iter()) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `[1, 2, 3].iter().collect::<Vec<_>>()`
|
||||
|
||||
error: usage of `FromIterator::from_iter`
|
||||
--> $DIR/from_iter_instead_of_collect.rs:47:15
|
||||
|
|
||||
LL | for _i in Vec::<&i32>::from_iter([1, 2, 3].iter()) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `[1, 2, 3].iter().collect::<Vec<&i32>>()`
|
||||
|
||||
error: aborting due to 14 previous errors
|
||||
|
||||
|
|
|
@ -16,4 +16,12 @@ fn main() {
|
|||
let _ = Box::new(());
|
||||
let _ = Droppable;
|
||||
let _ = Some(Droppable);
|
||||
|
||||
// no lint for reference
|
||||
let _ = droppable_ref();
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
fn droppable_ref() -> &'static mut Droppable {
|
||||
unimplemented!()
|
||||
}
|
||||
|
|
76
tests/ui/manual_flatten.rs
Normal file
76
tests/ui/manual_flatten.rs
Normal file
|
@ -0,0 +1,76 @@
|
|||
#![warn(clippy::manual_flatten)]
|
||||
|
||||
fn main() {
|
||||
// Test for loop over implicitly adjusted `Iterator` with `if let` expression
|
||||
let x = vec![Some(1), Some(2), Some(3)];
|
||||
for n in x {
|
||||
if let Some(y) = n {
|
||||
println!("{}", y);
|
||||
}
|
||||
}
|
||||
|
||||
// Test for loop over implicitly implicitly adjusted `Iterator` with `if let` statement
|
||||
let y: Vec<Result<i32, i32>> = vec![];
|
||||
for n in y.clone() {
|
||||
if let Ok(n) = n {
|
||||
println!("{}", n);
|
||||
};
|
||||
}
|
||||
|
||||
// Test for loop over by reference
|
||||
for n in &y {
|
||||
if let Ok(n) = n {
|
||||
println!("{}", n);
|
||||
}
|
||||
}
|
||||
|
||||
// Test for loop over an implicit reference
|
||||
// Note: if `clippy::manual_flatten` is made autofixable, this case will
|
||||
// lead to a follow-up lint `clippy::into_iter_on_ref`
|
||||
let z = &y;
|
||||
for n in z {
|
||||
if let Ok(n) = n {
|
||||
println!("{}", n);
|
||||
}
|
||||
}
|
||||
|
||||
// Test for loop over `Iterator` with `if let` expression
|
||||
let z = vec![Some(1), Some(2), Some(3)];
|
||||
let z = z.iter();
|
||||
for n in z {
|
||||
if let Some(m) = n {
|
||||
println!("{}", m);
|
||||
}
|
||||
}
|
||||
|
||||
// Using the `None` variant should not trigger the lint
|
||||
// Note: for an autofixable suggestion, the binding in the for loop has to take the
|
||||
// name of the binding in the `if let`
|
||||
let z = vec![Some(1), Some(2), Some(3)];
|
||||
for n in z {
|
||||
if n.is_none() {
|
||||
println!("Nada.");
|
||||
}
|
||||
}
|
||||
|
||||
// Using the `Err` variant should not trigger the lint
|
||||
for n in y.clone() {
|
||||
if let Err(e) = n {
|
||||
println!("Oops: {}!", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Having an else clause should not trigger the lint
|
||||
for n in y.clone() {
|
||||
if let Ok(n) = n {
|
||||
println!("{}", n);
|
||||
} else {
|
||||
println!("Oops!");
|
||||
}
|
||||
}
|
||||
|
||||
// Using manual flatten should not trigger the lint
|
||||
for n in vec![Some(1), Some(2), Some(3)].iter().flatten() {
|
||||
println!("{}", n);
|
||||
}
|
||||
}
|
108
tests/ui/manual_flatten.stderr
Normal file
108
tests/ui/manual_flatten.stderr
Normal file
|
@ -0,0 +1,108 @@
|
|||
error: unnecessary `if let` since only the `Some` variant of the iterator element is used
|
||||
--> $DIR/manual_flatten.rs:6:5
|
||||
|
|
||||
LL | for n in x {
|
||||
| ^ - help: try: `x.into_iter().flatten()`
|
||||
| _____|
|
||||
| |
|
||||
LL | | if let Some(y) = n {
|
||||
LL | | println!("{}", y);
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
= note: `-D clippy::manual-flatten` implied by `-D warnings`
|
||||
help: ...and remove the `if let` statement in the for loop
|
||||
--> $DIR/manual_flatten.rs:7:9
|
||||
|
|
||||
LL | / if let Some(y) = n {
|
||||
LL | | println!("{}", y);
|
||||
LL | | }
|
||||
| |_________^
|
||||
|
||||
error: unnecessary `if let` since only the `Ok` variant of the iterator element is used
|
||||
--> $DIR/manual_flatten.rs:14:5
|
||||
|
|
||||
LL | for n in y.clone() {
|
||||
| ^ --------- help: try: `y.clone().into_iter().flatten()`
|
||||
| _____|
|
||||
| |
|
||||
LL | | if let Ok(n) = n {
|
||||
LL | | println!("{}", n);
|
||||
LL | | };
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: ...and remove the `if let` statement in the for loop
|
||||
--> $DIR/manual_flatten.rs:15:9
|
||||
|
|
||||
LL | / if let Ok(n) = n {
|
||||
LL | | println!("{}", n);
|
||||
LL | | };
|
||||
| |_________^
|
||||
|
||||
error: unnecessary `if let` since only the `Ok` variant of the iterator element is used
|
||||
--> $DIR/manual_flatten.rs:21:5
|
||||
|
|
||||
LL | for n in &y {
|
||||
| ^ -- help: try: `y.iter().flatten()`
|
||||
| _____|
|
||||
| |
|
||||
LL | | if let Ok(n) = n {
|
||||
LL | | println!("{}", n);
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: ...and remove the `if let` statement in the for loop
|
||||
--> $DIR/manual_flatten.rs:22:9
|
||||
|
|
||||
LL | / if let Ok(n) = n {
|
||||
LL | | println!("{}", n);
|
||||
LL | | }
|
||||
| |_________^
|
||||
|
||||
error: unnecessary `if let` since only the `Ok` variant of the iterator element is used
|
||||
--> $DIR/manual_flatten.rs:31:5
|
||||
|
|
||||
LL | for n in z {
|
||||
| ^ - help: try: `z.into_iter().flatten()`
|
||||
| _____|
|
||||
| |
|
||||
LL | | if let Ok(n) = n {
|
||||
LL | | println!("{}", n);
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: ...and remove the `if let` statement in the for loop
|
||||
--> $DIR/manual_flatten.rs:32:9
|
||||
|
|
||||
LL | / if let Ok(n) = n {
|
||||
LL | | println!("{}", n);
|
||||
LL | | }
|
||||
| |_________^
|
||||
|
||||
error: unnecessary `if let` since only the `Some` variant of the iterator element is used
|
||||
--> $DIR/manual_flatten.rs:40:5
|
||||
|
|
||||
LL | for n in z {
|
||||
| ^ - help: try: `z.flatten()`
|
||||
| _____|
|
||||
| |
|
||||
LL | | if let Some(m) = n {
|
||||
LL | | println!("{}", m);
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: ...and remove the `if let` statement in the for loop
|
||||
--> $DIR/manual_flatten.rs:41:9
|
||||
|
|
||||
LL | / if let Some(m) = n {
|
||||
LL | | println!("{}", m);
|
||||
LL | | }
|
||||
| |_________^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
55
tests/ui/semicolon_if_nothing_returned.rs
Normal file
55
tests/ui/semicolon_if_nothing_returned.rs
Normal file
|
@ -0,0 +1,55 @@
|
|||
#![warn(clippy::semicolon_if_nothing_returned)]
|
||||
#![feature(label_break_value)]
|
||||
|
||||
fn get_unit() {}
|
||||
|
||||
// the functions below trigger the lint
|
||||
fn main() {
|
||||
println!("Hello")
|
||||
}
|
||||
|
||||
fn hello() {
|
||||
get_unit()
|
||||
}
|
||||
|
||||
fn basic101(x: i32) {
|
||||
let y: i32;
|
||||
y = x + 1
|
||||
}
|
||||
|
||||
// this is fine
|
||||
fn print_sum(a: i32, b: i32) {
|
||||
println!("{}", a + b);
|
||||
assert_eq!(true, false);
|
||||
}
|
||||
|
||||
fn foo(x: i32) {
|
||||
let y: i32;
|
||||
if x < 1 {
|
||||
y = 4;
|
||||
} else {
|
||||
y = 5;
|
||||
}
|
||||
}
|
||||
|
||||
fn bar(x: i32) {
|
||||
let y: i32;
|
||||
match x {
|
||||
1 => y = 4,
|
||||
_ => y = 32,
|
||||
}
|
||||
}
|
||||
|
||||
fn foobar(x: i32) {
|
||||
let y: i32;
|
||||
'label: {
|
||||
y = x + 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn loop_test(x: i32) {
|
||||
let y: i32;
|
||||
for &ext in &["stdout", "stderr", "fixed"] {
|
||||
println!("{}", ext);
|
||||
}
|
||||
}
|
22
tests/ui/semicolon_if_nothing_returned.stderr
Normal file
22
tests/ui/semicolon_if_nothing_returned.stderr
Normal file
|
@ -0,0 +1,22 @@
|
|||
error: consider adding a `;` to the last statement for consistent formatting
|
||||
--> $DIR/semicolon_if_nothing_returned.rs:8:5
|
||||
|
|
||||
LL | println!("Hello")
|
||||
| ^^^^^^^^^^^^^^^^^ help: add a `;` here: `println!("Hello");`
|
||||
|
|
||||
= note: `-D clippy::semicolon-if-nothing-returned` implied by `-D warnings`
|
||||
|
||||
error: consider adding a `;` to the last statement for consistent formatting
|
||||
--> $DIR/semicolon_if_nothing_returned.rs:12:5
|
||||
|
|
||||
LL | get_unit()
|
||||
| ^^^^^^^^^^ help: add a `;` here: `get_unit();`
|
||||
|
||||
error: consider adding a `;` to the last statement for consistent formatting
|
||||
--> $DIR/semicolon_if_nothing_returned.rs:17:5
|
||||
|
|
||||
LL | y = x + 1
|
||||
| ^^^^^^^^^ help: add a `;` here: `y = x + 1;`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
|
@ -7,7 +7,7 @@ fn main() {
|
|||
let one_more_f64_nan = 0.0f64 / 0.0f64;
|
||||
let zero = 0.0;
|
||||
let other_zero = 0.0;
|
||||
let other_nan = zero / other_zero; // fine - this lint doesn't propegate constants.
|
||||
let other_nan = zero / other_zero; // fine - this lint doesn't propagate constants.
|
||||
let not_nan = 2.0 / 0.0; // not an error: 2/0 = inf
|
||||
let also_not_nan = 0.0 / 2.0; // not an error: 0/2 = 0
|
||||
}
|
||||
|
|
|
@ -23,6 +23,12 @@ fn check_that_clippy_lints_has_the_same_version_as_clippy() {
|
|||
|
||||
#[test]
|
||||
fn check_that_clippy_has_the_same_major_version_as_rustc() {
|
||||
// do not run this test inside the upstream rustc repo:
|
||||
// https://github.com/rust-lang/rust-clippy/issues/6683
|
||||
if option_env!("RUSTC_TEST_SUITE").is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
let clippy_version = rustc_tools_util::get_version_info!();
|
||||
let clippy_major = clippy_version.major;
|
||||
let clippy_minor = clippy_version.minor;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[relabel]
|
||||
allow-unauthenticated = [
|
||||
"A-*", "C-*", "E-*", "L-*", "M-*", "O-*", "P-*", "S-*", "T-*",
|
||||
"A-*", "C-*", "E-*", "I-*", "L-*", "P-*", "S-*", "T-*",
|
||||
"good-first-issue"
|
||||
]
|
||||
|
||||
|
|
Loading…
Reference in a new issue