diff options
Diffstat (limited to 'src/tools/clippy/tests')
49 files changed, 1504 insertions, 511 deletions
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs index 64253514fbe..9754254cdd0 100644 --- a/src/tools/clippy/tests/compile-test.rs +++ b/src/tools/clippy/tests/compile-test.rs @@ -1,25 +1,31 @@ -// We need this feature as it changes `dylib` linking behavior and allows us to link to -// `rustc_driver`. -#![feature(rustc_private)] +#![feature(rustc_private, let_chains)] #![warn(rust_2018_idioms, unused_lifetimes)] #![allow(unused_extern_crates)] +use cargo_metadata::diagnostic::{Applicability, Diagnostic}; +use cargo_metadata::Message; +use clippy_config::ClippyConfiguration; +use clippy_lints::declared_lints::LINTS; +use clippy_lints::deprecated_lints::{DEPRECATED, DEPRECATED_VERSION, RENAMED}; +use clippy_lints::LintInfo; +use serde::{Deserialize, Serialize}; +use test_utils::IS_RUSTC_TEST_SUITE; use ui_test::custom_flags::rustfix::RustfixMode; +use ui_test::custom_flags::Flag; use ui_test::spanned::Spanned; +use ui_test::test_result::TestRun; use ui_test::{status_emitter, Args, CommandBuilder, Config, Match, OutputConflictHandling}; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashMap}; use std::env::{self, set_var, var_os}; use std::ffi::{OsStr, OsString}; -use std::fs; +use std::fmt::Write; use std::path::{Path, PathBuf}; -use std::sync::LazyLock; -use test_utils::IS_RUSTC_TEST_SUITE; +use std::sync::mpsc::{channel, Sender}; +use std::{fs, iter, thread}; // Test dependencies may need an `extern crate` here to ensure that they show up // in the depinfo file (otherwise cargo thinks they are unused) -extern crate clippy_lints; -extern crate clippy_utils; extern crate futures; extern crate if_chain; extern crate itertools; @@ -55,7 +61,7 @@ static TEST_DEPENDENCIES: &[&str] = &[ /// dependencies must be added to Cargo.toml at the project root. Test /// dependencies that are not *directly* used by this test module require an /// `extern crate` declaration. -static EXTERN_FLAGS: LazyLock<Vec<String>> = LazyLock::new(|| { +fn extern_flags() -> Vec<String> { let current_exe_depinfo = { let mut path = env::current_exe().unwrap(); path.set_extension("d"); @@ -103,70 +109,93 @@ static EXTERN_FLAGS: LazyLock<Vec<String>> = LazyLock::new(|| { .into_iter() .map(|(name, path)| format!("--extern={name}={path}")) .collect() -}); +} // whether to run internal tests or not const RUN_INTERNAL_TESTS: bool = cfg!(feature = "internal"); -fn base_config(test_dir: &str) -> (Config, Args) { - let mut args = Args::test().unwrap(); - args.bless |= var_os("RUSTC_BLESS").is_some_and(|v| v != "0"); - - let target_dir = PathBuf::from(var_os("CARGO_TARGET_DIR").unwrap_or_else(|| "target".into())); - let mut config = Config { - output_conflict_handling: OutputConflictHandling::Error, - filter_files: env::var("TESTNAME") - .map(|filters| filters.split(',').map(str::to_string).collect()) - .unwrap_or_default(), - target: None, - bless_command: Some("cargo uibless".into()), - out_dir: target_dir.join("ui_test"), - ..Config::rustc(Path::new("tests").join(test_dir)) - }; - config.comment_defaults.base().exit_status = None.into(); - config.comment_defaults.base().require_annotations = None.into(); - config - .comment_defaults - .base() - .set_custom("rustfix", RustfixMode::Everything); - config.comment_defaults.base().diagnostic_code_prefix = Some(Spanned::dummy("clippy::".into())).into(); - config.with_args(&args); - let current_exe_path = env::current_exe().unwrap(); - let deps_path = current_exe_path.parent().unwrap(); - let profile_path = deps_path.parent().unwrap(); - - config.program.args.extend( - [ - "--emit=metadata", - "-Aunused", - "-Ainternal_features", - "-Zui-testing", - "-Zdeduplicate-diagnostics=no", - "-Dwarnings", - &format!("-Ldependency={}", deps_path.display()), - ] - .map(OsString::from), - ); - - config.program.args.extend(EXTERN_FLAGS.iter().map(OsString::from)); - // Prevent rustc from creating `rustc-ice-*` files the console output is enough. - config.program.envs.push(("RUSTC_ICE".into(), Some("0".into()))); +struct TestContext { + args: Args, + extern_flags: Vec<String>, + diagnostic_collector: Option<DiagnosticCollector>, + collector_thread: Option<thread::JoinHandle<()>>, +} - if let Some(host_libs) = option_env!("HOST_LIBS") { - let dep = format!("-Ldependency={}", Path::new(host_libs).join("deps").display()); - config.program.args.push(dep.into()); +impl TestContext { + fn new() -> Self { + let mut args = Args::test().unwrap(); + args.bless |= var_os("RUSTC_BLESS").is_some_and(|v| v != "0"); + let (diagnostic_collector, collector_thread) = var_os("COLLECT_METADATA") + .is_some() + .then(DiagnosticCollector::spawn) + .unzip(); + Self { + args, + extern_flags: extern_flags(), + diagnostic_collector, + collector_thread, + } } - config.program.program = profile_path.join(if cfg!(windows) { - "clippy-driver.exe" - } else { - "clippy-driver" - }); - (config, args) + fn base_config(&self, test_dir: &str) -> Config { + let target_dir = PathBuf::from(var_os("CARGO_TARGET_DIR").unwrap_or_else(|| "target".into())); + let mut config = Config { + output_conflict_handling: OutputConflictHandling::Error, + filter_files: env::var("TESTNAME") + .map(|filters| filters.split(',').map(str::to_string).collect()) + .unwrap_or_default(), + target: None, + bless_command: Some("cargo uibless".into()), + out_dir: target_dir.join("ui_test"), + ..Config::rustc(Path::new("tests").join(test_dir)) + }; + let defaults = config.comment_defaults.base(); + defaults.exit_status = None.into(); + defaults.require_annotations = None.into(); + defaults.diagnostic_code_prefix = Some(Spanned::dummy("clippy::".into())).into(); + defaults.set_custom("rustfix", RustfixMode::Everything); + if let Some(collector) = self.diagnostic_collector.clone() { + defaults.set_custom("diagnostic-collector", collector); + } + config.with_args(&self.args); + let current_exe_path = env::current_exe().unwrap(); + let deps_path = current_exe_path.parent().unwrap(); + let profile_path = deps_path.parent().unwrap(); + + config.program.args.extend( + [ + "--emit=metadata", + "-Aunused", + "-Ainternal_features", + "-Zui-testing", + "-Zdeduplicate-diagnostics=no", + "-Dwarnings", + &format!("-Ldependency={}", deps_path.display()), + ] + .map(OsString::from), + ); + + config.program.args.extend(self.extern_flags.iter().map(OsString::from)); + // Prevent rustc from creating `rustc-ice-*` files the console output is enough. + config.program.envs.push(("RUSTC_ICE".into(), Some("0".into()))); + + if let Some(host_libs) = option_env!("HOST_LIBS") { + let dep = format!("-Ldependency={}", Path::new(host_libs).join("deps").display()); + config.program.args.push(dep.into()); + } + + config.program.program = profile_path.join(if cfg!(windows) { + "clippy-driver.exe" + } else { + "clippy-driver" + }); + + config + } } -fn run_ui() { - let (mut config, args) = base_config("ui"); +fn run_ui(cx: &TestContext) { + let mut config = cx.base_config("ui"); config .program .envs @@ -176,30 +205,29 @@ fn run_ui() { vec![config], ui_test::default_file_filter, ui_test::default_per_file_config, - status_emitter::Text::from(args.format), + status_emitter::Text::from(cx.args.format), ) .unwrap(); } -fn run_internal_tests() { - // only run internal tests with the internal-tests feature +fn run_internal_tests(cx: &TestContext) { if !RUN_INTERNAL_TESTS { return; } - let (mut config, args) = base_config("ui-internal"); + let mut config = cx.base_config("ui-internal"); config.bless_command = Some("cargo uitest --features internal -- -- --bless".into()); ui_test::run_tests_generic( vec![config], ui_test::default_file_filter, ui_test::default_per_file_config, - status_emitter::Text::from(args.format), + status_emitter::Text::from(cx.args.format), ) .unwrap(); } -fn run_ui_toml() { - let (mut config, args) = base_config("ui-toml"); +fn run_ui_toml(cx: &TestContext) { + let mut config = cx.base_config("ui-toml"); config .comment_defaults @@ -217,19 +245,19 @@ fn run_ui_toml() { .envs .push(("CLIPPY_CONF_DIR".into(), Some(path.parent().unwrap().into()))); }, - status_emitter::Text::from(args.format), + status_emitter::Text::from(cx.args.format), ) .unwrap(); } // Allow `Default::default` as `OptWithSpan` is not nameable #[allow(clippy::default_trait_access)] -fn run_ui_cargo() { +fn run_ui_cargo(cx: &TestContext) { if IS_RUSTC_TEST_SUITE { return; } - let (mut config, args) = base_config("ui-cargo"); + let mut config = cx.base_config("ui-cargo"); config.program.input_file_flag = CommandBuilder::cargo().input_file_flag; config.program.out_dir_flag = CommandBuilder::cargo().out_dir_flag; config.program.args = vec!["clippy".into(), "--color".into(), "never".into(), "--quiet".into()]; @@ -264,23 +292,25 @@ fn run_ui_cargo() { .then(|| ui_test::default_any_file_filter(path, config) && !ignored_32bit(path)) }, |_config, _file_contents| {}, - status_emitter::Text::from(args.format), + status_emitter::Text::from(cx.args.format), ) .unwrap(); } fn main() { set_var("CLIPPY_DISABLE_DOCS_LINKS", "true"); + + let cx = TestContext::new(); + // The SPEEDTEST_* env variables can be used to check Clippy's performance on your PR. It runs the // affected test 1000 times and gets the average. if let Ok(speedtest) = std::env::var("SPEEDTEST") { println!("----------- STARTING SPEEDTEST -----------"); let f = match speedtest.as_str() { - "ui" => run_ui as fn(), - "cargo" => run_ui_cargo as fn(), - "toml" => run_ui_toml as fn(), - "internal" => run_internal_tests as fn(), - "ui-cargo-toml-metadata" => ui_cargo_toml_metadata as fn(), + "ui" => run_ui, + "cargo" => run_ui_cargo, + "toml" => run_ui_toml, + "internal" => run_internal_tests, _ => panic!("unknown speedtest: {speedtest} || accepted speedtests are: [ui, cargo, toml, internal]"), }; @@ -297,7 +327,7 @@ fn main() { let mut sum = 0; for _ in 0..iterations { let start = std::time::Instant::now(); - f(); + f(&cx); sum += start.elapsed().as_millis(); } println!( @@ -306,11 +336,17 @@ fn main() { sum / u128::from(iterations) ); } else { - run_ui(); - run_ui_toml(); - run_ui_cargo(); - run_internal_tests(); + run_ui(&cx); + run_ui_toml(&cx); + run_ui_cargo(&cx); + run_internal_tests(&cx); + drop(cx.diagnostic_collector); + ui_cargo_toml_metadata(); + + if let Some(thread) = cx.collector_thread { + thread.join().unwrap(); + } } } @@ -349,3 +385,180 @@ fn ui_cargo_toml_metadata() { ); } } + +#[derive(Deserialize)] +#[serde(untagged)] +enum DiagnosticOrMessage { + Diagnostic(Diagnostic), + Message(Message), +} + +/// Collects applicabilities from the diagnostics produced for each UI test, producing the +/// `util/gh-pages/lints.json` file used by <https://rust-lang.github.io/rust-clippy/> +#[derive(Debug, Clone)] +struct DiagnosticCollector { + sender: Sender<Vec<u8>>, +} + +impl DiagnosticCollector { + #[allow(clippy::assertions_on_constants)] + fn spawn() -> (Self, thread::JoinHandle<()>) { + assert!(!IS_RUSTC_TEST_SUITE && !RUN_INTERNAL_TESTS); + + let (sender, receiver) = channel::<Vec<u8>>(); + + let handle = thread::spawn(|| { + let mut applicabilities = HashMap::new(); + + for stderr in receiver { + for line in stderr.split(|&byte| byte == b'\n') { + let diag = match serde_json::from_slice(line) { + Ok(DiagnosticOrMessage::Diagnostic(diag)) => diag, + Ok(DiagnosticOrMessage::Message(Message::CompilerMessage(message))) => message.message, + _ => continue, + }; + + if let Some(lint) = diag.code.as_ref().and_then(|code| code.code.strip_prefix("clippy::")) { + let applicability = applicabilities + .entry(lint.to_string()) + .or_insert(Applicability::Unspecified); + let diag_applicability = diag + .children + .iter() + .flat_map(|child| &child.spans) + .filter_map(|span| span.suggestion_applicability.clone()) + .max_by_key(applicability_ord); + if let Some(diag_applicability) = diag_applicability + && applicability_ord(&diag_applicability) > applicability_ord(applicability) + { + *applicability = diag_applicability; + } + } + } + } + + let configs = clippy_config::get_configuration_metadata(); + let mut metadata: Vec<LintMetadata> = LINTS + .iter() + .map(|lint| LintMetadata::new(lint, &applicabilities, &configs)) + .chain( + iter::zip(DEPRECATED, DEPRECATED_VERSION) + .map(|((lint, reason), version)| LintMetadata::new_deprecated(lint, reason, version)), + ) + .collect(); + metadata.sort_unstable_by(|a, b| a.id.cmp(&b.id)); + + let json = serde_json::to_string_pretty(&metadata).unwrap(); + fs::write("util/gh-pages/lints.json", json).unwrap(); + }); + + (Self { sender }, handle) + } +} + +fn applicability_ord(applicability: &Applicability) -> u8 { + match applicability { + Applicability::MachineApplicable => 4, + Applicability::HasPlaceholders => 3, + Applicability::MaybeIncorrect => 2, + Applicability::Unspecified => 1, + _ => unimplemented!(), + } +} + +impl Flag for DiagnosticCollector { + fn post_test_action( + &self, + _config: &ui_test::per_test_config::TestConfig<'_>, + _cmd: &mut std::process::Command, + output: &std::process::Output, + _build_manager: &ui_test::build_manager::BuildManager<'_>, + ) -> Result<Vec<TestRun>, ui_test::Errored> { + if !output.stderr.is_empty() { + self.sender.send(output.stderr.clone()).unwrap(); + } + Ok(Vec::new()) + } + + fn clone_inner(&self) -> Box<dyn Flag> { + Box::new(self.clone()) + } + + fn must_be_unique(&self) -> bool { + true + } +} + +#[derive(Debug, Serialize)] +struct LintMetadata { + id: String, + id_location: Option<&'static str>, + group: &'static str, + level: &'static str, + docs: String, + version: &'static str, + applicability: Applicability, +} + +impl LintMetadata { + fn new(lint: &LintInfo, applicabilities: &HashMap<String, Applicability>, configs: &[ClippyConfiguration]) -> Self { + let name = lint.name_lower(); + let applicability = applicabilities + .get(&name) + .cloned() + .unwrap_or(Applicability::Unspecified); + let past_names = RENAMED + .iter() + .filter(|(_, new_name)| new_name.strip_prefix("clippy::") == Some(&name)) + .map(|(old_name, _)| old_name.strip_prefix("clippy::").unwrap()) + .collect::<Vec<_>>(); + let mut docs = lint.explanation.to_string(); + if !past_names.is_empty() { + docs.push_str("\n### Past names\n\n"); + for past_name in past_names { + writeln!(&mut docs, " * {past_name}").unwrap(); + } + } + let configs: Vec<_> = configs + .iter() + .filter(|conf| conf.lints.contains(&name.as_str())) + .collect(); + if !configs.is_empty() { + docs.push_str("\n### Configuration\n\n"); + for config in configs { + writeln!(&mut docs, "{config}").unwrap(); + } + } + Self { + id: name, + id_location: Some(lint.location), + group: lint.category_str(), + level: lint.lint.default_level.as_str(), + docs, + version: lint.version.unwrap(), + applicability, + } + } + + fn new_deprecated(name: &str, reason: &str, version: &'static str) -> Self { + // The reason starts with a lowercase letter and ends without a period. + // This needs to be fixed for the website. + let mut reason = reason.to_owned(); + if let Some(reason) = reason.get_mut(0..1) { + reason.make_ascii_uppercase(); + } + Self { + id: name.strip_prefix("clippy::").unwrap().into(), + id_location: None, + group: "deprecated", + level: "none", + version, + docs: format!( + "### What it does\n\n\ + Nothing. This lint has been deprecated\n\n\ + ### Deprecation reason\n\n{reason}.\n", + ), + applicability: Applicability::Unspecified, + } + } +} diff --git a/src/tools/clippy/tests/config-metadata.rs b/src/tools/clippy/tests/config-metadata.rs new file mode 100644 index 00000000000..3e3711873ba --- /dev/null +++ b/src/tools/clippy/tests/config-metadata.rs @@ -0,0 +1,78 @@ +#![feature(rustc_private)] + +use clippy_config::{get_configuration_metadata, ClippyConfiguration}; +use itertools::Itertools; +use regex::Regex; +use std::borrow::Cow; +use std::{env, fs}; + +fn metadata() -> impl Iterator<Item = ClippyConfiguration> { + get_configuration_metadata() + .into_iter() + .filter(|config| config.deprecation_reason.is_none()) + .filter(|config| !config.lints.is_empty()) +} + +#[test] +fn book() { + let path = "book/src/lint_configuration.md"; + let current = fs::read_to_string(path).unwrap(); + + let configs = metadata().map(|conf| conf.to_markdown_paragraph()).join("\n"); + let expected = format!( + r#"<!-- +This file is generated by `cargo bless --test config-metadata`. +Please use that command to update the file and do not edit it by hand. +--> + +# Lint Configuration Options + +The following list shows each configuration option, along with a description, its default value, an example +and lints affected. + +--- + +{} +"#, + configs.trim(), + ); + + if current != expected { + if env::var_os("RUSTC_BLESS").is_some_and(|v| v != "0") { + fs::write(path, expected).unwrap(); + } else { + panic!("`{path}` is out of date, run `cargo bless --test config-metadata` to update it"); + } + } +} + +#[test] +fn changelog() { + let path = "CHANGELOG.md"; + let current = fs::read_to_string(path).unwrap(); + + let configs = metadata().map(|conf| conf.to_markdown_link()).join("\n"); + + let re = Regex::new( + "(?s)\ + (<!-- begin autogenerated links to configuration documentation -->)\ + .*\ + (<!-- end autogenerated links to configuration documentation -->)\ + ", + ) + .unwrap(); + let expected = re.replace(¤t, format!("$1\n{configs}\n$2")); + + assert!( + matches!(expected, Cow::Owned(_)), + "failed to find configuration section in `{path}`" + ); + + if current != expected { + if env::var_os("RUSTC_BLESS").is_some_and(|v| v != "0") { + fs::write(path, expected.as_bytes()).unwrap(); + } else { + panic!("`{path}` is out of date, run `cargo bless --test config-metadata` to update it"); + } + } +} diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr index 1cc1034cd89..d24b0cd6162 100644 --- a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr +++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr @@ -1,29 +1,44 @@ error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:40:5 + --> tests/ui-toml/absolute_paths/absolute_paths.rs:14:13 | -LL | std::f32::MAX; - | ^^^^^^^^^^^^^ +LL | let _ = std::path::is_separator(' '); + | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::absolute-paths` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::absolute_paths)]` +note: the lint level is defined here + --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9 + | +LL | #![deny(clippy::absolute_paths)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:20:13 + | +LL | let _ = ::std::path::MAIN_SEPARATOR; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13 + | +LL | let _ = std::collections::hash_map::HashMap::<i32, i32>::new(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:41:5 + --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:31 | -LL | core::f32::MAX; - | ^^^^^^^^^^^^^^ +LL | let _: &std::path::Path = std::path::Path::new(""); + | ^^^^^^^^^^^^^^^ error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:42:5 + --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:13 | -LL | ::core::f32::MAX; - | ^^^^^^^^^^^^^^^^ +LL | let _: &std::path::Path = std::path::Path::new(""); + | ^^^^^^^^^^^^^^^ error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:58:5 + --> tests/ui-toml/absolute_paths/absolute_paths.rs:43:13 | -LL | ::std::f32::MAX; - | ^^^^^^^^^^^^^^^ +LL | let _ = std::option::Option::None::<i32>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_long.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_long.stderr new file mode 100644 index 00000000000..0cc6566af3a --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_long.stderr @@ -0,0 +1,14 @@ +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13 + | +LL | let _ = std::collections::hash_map::HashMap::<i32, i32>::new(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9 + | +LL | #![deny(clippy::absolute_paths)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.default.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.default.stderr new file mode 100644 index 00000000000..53aa9030e0d --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.default.stderr @@ -0,0 +1,80 @@ +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:14:13 + | +LL | let _ = std::path::is_separator(' '); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9 + | +LL | #![deny(clippy::absolute_paths)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:20:13 + | +LL | let _ = ::std::path::MAIN_SEPARATOR; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13 + | +LL | let _ = std::collections::hash_map::HashMap::<i32, i32>::new(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:31 + | +LL | let _: &std::path::Path = std::path::Path::new(""); + | ^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:13 + | +LL | let _: &std::path::Path = std::path::Path::new(""); + | ^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:37:13 + | +LL | let _ = ::core::clone::Clone::clone(&0i32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:40:13 + | +LL | let _ = <i32 as core::clone::Clone>::clone(&0i32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:43:13 + | +LL | let _ = std::option::Option::None::<i32>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:17 + | +LL | impl<T: core::cmp::Eq> core::fmt::Display for X<T> + | ^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:70:18 + | +LL | where T: core::clone::Clone + | ^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:32 + | +LL | impl<T: core::cmp::Eq> core::fmt::Display for X<T> + | ^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:116:5 + | +LL | crate::m1::S + | ^^^^^^^^^^^^ + +error: aborting due to 12 previous errors + diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr deleted file mode 100644 index f342ebf6632..00000000000 --- a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr +++ /dev/null @@ -1,71 +0,0 @@ -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:40:5 - | -LL | std::f32::MAX; - | ^^^^^^^^^^^^^ - | - = note: `-D clippy::absolute-paths` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::absolute_paths)]` - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:41:5 - | -LL | core::f32::MAX; - | ^^^^^^^^^^^^^^ - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:42:5 - | -LL | ::core::f32::MAX; - | ^^^^^^^^^^^^^^^^ - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:43:5 - | -LL | crate::a::b::c::C; - | ^^^^^^^^^^^^^^^^^ - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:44:5 - | -LL | crate::a::b::c::d::e::f::F; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:45:5 - | -LL | crate::a::A; - | ^^^^^^^^^^^ - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:46:5 - | -LL | crate::a::b::B; - | ^^^^^^^^^^^^^^ - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:47:5 - | -LL | crate::a::b::c::C::ZERO; - | ^^^^^^^^^^^^^^^^^ - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:48:5 - | -LL | helper::b::c::d::e::f(); - | ^^^^^^^^^^^^^^^^^^^^^ - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:49:5 - | -LL | ::helper::b::c::d::e::f(); - | ^^^^^^^^^^^^^^^^^^^^^^^ - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:58:5 - | -LL | ::std::f32::MAX; - | ^^^^^^^^^^^^^^^ - -error: aborting due to 11 previous errors - diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr new file mode 100644 index 00000000000..70d71f6c4ea --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr @@ -0,0 +1,98 @@ +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:14:13 + | +LL | let _ = std::path::is_separator(' '); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9 + | +LL | #![deny(clippy::absolute_paths)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:20:13 + | +LL | let _ = ::std::path::MAIN_SEPARATOR; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13 + | +LL | let _ = std::collections::hash_map::HashMap::<i32, i32>::new(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:31 + | +LL | let _: &std::path::Path = std::path::Path::new(""); + | ^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:13 + | +LL | let _: &std::path::Path = std::path::Path::new(""); + | ^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:37:13 + | +LL | let _ = ::core::clone::Clone::clone(&0i32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:40:13 + | +LL | let _ = <i32 as core::clone::Clone>::clone(&0i32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:43:13 + | +LL | let _ = std::option::Option::None::<i32>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:17 + | +LL | impl<T: core::cmp::Eq> core::fmt::Display for X<T> + | ^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:70:18 + | +LL | where T: core::clone::Clone + | ^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:32 + | +LL | impl<T: core::cmp::Eq> core::fmt::Display for X<T> + | ^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:113:14 + | +LL | pub const _: crate::S = { + | ^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:114:9 + | +LL | let crate::S = m1::S; + | ^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:116:5 + | +LL | crate::m1::S + | ^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:122:14 + | +LL | let _ = <crate::S as Clone>::clone(&m1::S); + | ^^^^^^^^ + +error: aborting due to 15 previous errors + diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs index a828701bcee..c024f2f513c 100644 --- a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs +++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs @@ -1,97 +1,123 @@ //@aux-build:../../ui/auxiliary/proc_macros.rs -//@aux-build:helper.rs -//@revisions: allow_crates disallow_crates +//@revisions: default allow_crates allow_long no_short +//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/default //@[allow_crates] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/allow_crates -//@[disallow_crates] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/disallow_crates -#![allow(clippy::no_effect, clippy::legacy_numeric_constants, unused)] -#![warn(clippy::absolute_paths)] -#![feature(decl_macro)] +//@[allow_long] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/allow_long +//@[no_short] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/no_short +#![deny(clippy::absolute_paths)] -extern crate helper; -#[macro_use] extern crate proc_macros; +use proc_macros::{external, inline_macros, with_span}; -pub mod a { - pub mod b { - pub mod c { - pub struct C; +#[inline_macros] +fn main() { + let _ = std::path::is_separator(' '); + //~[default]^ absolute_paths + //~[allow_crates]| absolute_paths + //~[no_short]| absolute_paths - impl C { - pub const ZERO: u32 = 0; - } + // Make sure this is treated as having three path segments, not four. + let _ = ::std::path::MAIN_SEPARATOR; + //~[default]^ absolute_paths + //~[allow_crates]| absolute_paths + //~[no_short]| absolute_paths - pub mod d { - pub mod e { - pub mod f { - pub struct F; - } - } - } - } + let _ = std::collections::hash_map::HashMap::<i32, i32>::new(); //~ absolute_paths - pub struct B; - } + // Note `std::path::Path::new` is treated as having three parts + let _: &std::path::Path = std::path::Path::new(""); + //~[default]^ absolute_paths + //~[default]| absolute_paths + //~[allow_crates]| absolute_paths + //~[allow_crates]| absolute_paths + //~[no_short]| absolute_paths + //~[no_short]| absolute_paths - pub struct A; -} + // Treated as having three parts. + let _ = ::core::clone::Clone::clone(&0i32); + //~[default]^ absolute_paths + //~[no_short]| absolute_paths + let _ = <i32 as core::clone::Clone>::clone(&0i32); + //~[default]^ absolute_paths + //~[no_short]| absolute_paths + let _ = std::option::Option::None::<i32>; + //~[default]^ absolute_paths + //~[allow_crates]| absolute_paths + //~[no_short]| absolute_paths -fn main() { - f32::max(1.0, 2.0); - std::f32::MAX; - core::f32::MAX; - ::core::f32::MAX; - crate::a::b::c::C; - crate::a::b::c::d::e::f::F; - crate::a::A; - crate::a::b::B; - crate::a::b::c::C::ZERO; - helper::b::c::d::e::f(); - ::helper::b::c::d::e::f(); - fn b() -> a::b::B { - todo!() + { + // FIXME: macro calls should be checked. + let x = 1i32; + let _ = core::ptr::addr_of!(x); } - std::println!("a"); - let x = 1; - std::ptr::addr_of!(x); - // Test we handle max segments with `PathRoot` properly; this has 4 segments but we should say it - // has 3 - ::std::f32::MAX; - // Do not lint due to the above - ::helper::a(); - // Do not lint - helper::a(); - use crate::a::b::c::C; - use a::b; - use std::f32::MAX; - a::b::c::d::e::f::F; - b::c::C; - fn a() -> a::A { - todo!() - } - use a::b::c; - fn c() -> c::C { - todo!() + { + // FIXME: derive macro paths should be checked. + #[derive(core::clone::Clone)] + struct S; } - fn d() -> Result<(), ()> { - todo!() + + { + use core::fmt; + use core::marker::PhantomData; + + struct X<T>(PhantomData<T>); + impl<T: core::cmp::Eq> core::fmt::Display for X<T> + //~[default]^ absolute_paths + //~[default]| absolute_paths + //~[no_short]| absolute_paths + //~[no_short]| absolute_paths + where T: core::clone::Clone + //~[no_short]^ absolute_paths + //~[default]| absolute_paths + { + fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { + Ok(()) + } + } } - external! { - crate::a::b::c::C::ZERO; + + { + mod m1 { + pub(crate) mod m2 { + pub(crate) const FOO: i32 = 0; + } + } + let _ = m1::m2::FOO; } - // For some reason, `path.span.from_expansion()` takes care of this for us + with_span! { span - crate::a::b::c::C::ZERO; + let _ = std::path::is_separator(' '); } - macro_rules! local_crate { - () => { - crate::a::b::c::C::ZERO; - }; + + external! { + let _ = std::path::is_separator(' '); } - macro local_crate_2_0() { - crate::a::b::c::C::ZERO; + + inline! { + let _ = std::path::is_separator(' '); } - local_crate!(); - local_crate_2_0!(); +} + +pub use core::cmp::Ordering; +pub use std::fs::File; + +#[derive(Clone)] +pub struct S; +mod m1 { + pub use crate::S; +} + +//~[no_short]v absolute_paths +pub const _: crate::S = { + let crate::S = m1::S; //~[no_short] absolute_paths + + crate::m1::S + //~[default]^ absolute_paths + //~[no_short]| absolute_paths +}; + +pub fn f() { + let _ = <crate::S as Clone>::clone(&m1::S); //~[no_short] absolute_paths } diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr new file mode 100644 index 00000000000..6fc495f0180 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr @@ -0,0 +1,14 @@ +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths_2015.rs:15:13 + | +LL | let _ = ::m1::m2::X; + | ^^^^^^^^^^^ + | +note: the lint level is defined here + --> tests/ui-toml/absolute_paths/absolute_paths_2015.rs:6:9 + | +LL | #![deny(clippy::absolute_paths)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.rs b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.rs new file mode 100644 index 00000000000..033c4780919 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.rs @@ -0,0 +1,16 @@ +//@revisions: default allow_crates +//@[default]rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/default +//@[allow_crates]rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/allow_crates +//@edition:2015 + +#![deny(clippy::absolute_paths)] + +mod m1 { + pub mod m2 { + pub struct X; + } +} + +fn main() { + let _ = ::m1::m2::X; //~[default] absolute_paths +} diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/allow_crates/clippy.toml b/src/tools/clippy/tests/ui-toml/absolute_paths/allow_crates/clippy.toml index 59a621e9d1d..9da49abcd31 100644 --- a/src/tools/clippy/tests/ui-toml/absolute_paths/allow_crates/clippy.toml +++ b/src/tools/clippy/tests/ui-toml/absolute_paths/allow_crates/clippy.toml @@ -1,2 +1 @@ -absolute-paths-max-segments = 2 -absolute-paths-allowed-crates = ["crate", "helper"] +absolute-paths-allowed-crates = ["core", "crate"] diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/allow_long/clippy.toml b/src/tools/clippy/tests/ui-toml/absolute_paths/allow_long/clippy.toml new file mode 100644 index 00000000000..5992fd1ed82 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/absolute_paths/allow_long/clippy.toml @@ -0,0 +1 @@ +absolute-paths-max-segments = 3 diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/auxiliary/helper.rs b/src/tools/clippy/tests/ui-toml/absolute_paths/auxiliary/helper.rs deleted file mode 100644 index 8e2678f5fe6..00000000000 --- a/src/tools/clippy/tests/ui-toml/absolute_paths/auxiliary/helper.rs +++ /dev/null @@ -1,11 +0,0 @@ -pub fn a() {} - -pub mod b { - pub mod c { - pub mod d { - pub mod e { - pub fn f() {} - } - } - } -} diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/default/clippy.toml b/src/tools/clippy/tests/ui-toml/absolute_paths/default/clippy.toml new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/absolute_paths/default/clippy.toml diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/disallow_crates/clippy.toml b/src/tools/clippy/tests/ui-toml/absolute_paths/disallow_crates/clippy.toml deleted file mode 100644 index d44d648c641..00000000000 --- a/src/tools/clippy/tests/ui-toml/absolute_paths/disallow_crates/clippy.toml +++ /dev/null @@ -1 +0,0 @@ -absolute-paths-max-segments = 2 diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/no_short/clippy.toml b/src/tools/clippy/tests/ui-toml/absolute_paths/no_short/clippy.toml new file mode 100644 index 00000000000..357524420c5 --- /dev/null +++ b/src/tools/clippy/tests/ui-toml/absolute_paths/no_short/clippy.toml @@ -0,0 +1 @@ +absolute-paths-max-segments = 0 diff --git a/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs b/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs index a312df5a43a..3dafea56514 100644 --- a/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs +++ b/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs @@ -1,7 +1,7 @@ //! Tests macro_metavars_in_unsafe with default configuration #![feature(decl_macro)] #![warn(clippy::macro_metavars_in_unsafe)] -#![allow(clippy::no_effect)] +#![allow(clippy::no_effect, clippy::not_unsafe_ptr_arg_deref)] #[macro_export] macro_rules! allow_works { @@ -237,6 +237,19 @@ macro_rules! nested_macros { }}; } +pub mod issue13219 { + #[macro_export] + macro_rules! m { + ($e:expr) => { + // Metavariable in a block tail expression + unsafe { $e } + }; + } + pub fn f(p: *const i32) -> i32 { + m!(*p) + } +} + fn main() { allow_works!(1); simple!(1); diff --git a/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr b/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr index d6b97f6fde1..6f0ebcbba02 100644 --- a/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr +++ b/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr @@ -1,4 +1,16 @@ error: this macro expands metavariables in an unsafe block + --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:245:13 + | +LL | unsafe { $e } + | ^^^^^^^^^^^^^ + | + = note: this allows the user of the macro to write unsafe code outside of an unsafe block + = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable + = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite + = note: `-D clippy::macro-metavars-in-unsafe` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::macro_metavars_in_unsafe)]` + +error: this macro expands metavariables in an unsafe block --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:19:9 | LL | / unsafe { @@ -10,8 +22,6 @@ LL | | } = note: this allows the user of the macro to write unsafe code outside of an unsafe block = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite - = note: `-D clippy::macro-metavars-in-unsafe` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::macro_metavars_in_unsafe)]` error: this macro expands metavariables in an unsafe block --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:30:9 @@ -183,5 +193,5 @@ LL | | } = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite -error: aborting due to 14 previous errors +error: aborting due to 15 previous errors diff --git a/src/tools/clippy/tests/ui/assigning_clones.fixed b/src/tools/clippy/tests/ui/assigning_clones.fixed index b376d55a402..09732d1a50c 100644 --- a/src/tools/clippy/tests/ui/assigning_clones.fixed +++ b/src/tools/clippy/tests/ui/assigning_clones.fixed @@ -396,3 +396,23 @@ impl<T: Clone> Clone for DerefWrapperWithClone<T> { *self = Self(source.0.clone()); } } + +#[cfg(test)] +mod test { + #[derive(Default)] + struct Data { + field: String, + } + + fn test_data() -> Data { + Data { + field: "default_value".to_string(), + } + } + + #[test] + fn test() { + let mut data = test_data(); + data.field = "override_value".to_owned(); + } +} diff --git a/src/tools/clippy/tests/ui/assigning_clones.rs b/src/tools/clippy/tests/ui/assigning_clones.rs index 11a5d4459c3..6be25ae17a5 100644 --- a/src/tools/clippy/tests/ui/assigning_clones.rs +++ b/src/tools/clippy/tests/ui/assigning_clones.rs @@ -396,3 +396,23 @@ impl<T: Clone> Clone for DerefWrapperWithClone<T> { *self = Self(source.0.clone()); } } + +#[cfg(test)] +mod test { + #[derive(Default)] + struct Data { + field: String, + } + + fn test_data() -> Data { + Data { + field: "default_value".to_string(), + } + } + + #[test] + fn test() { + let mut data = test_data(); + data.field = "override_value".to_owned(); + } +} diff --git a/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.stderr b/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.stderr index f7e659b10de..329be4d3662 100644 --- a/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.stderr +++ b/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.stderr @@ -2,7 +2,7 @@ error: called `unwrap` on `x` after checking its variant with `is_some` --> tests/ui/checked_unwrap/complex_conditionals_nested.rs:13:13 | LL | if x.is_some() { - | -------------- help: try: `if let Some(..) = x` + | -------------- help: try: `if let Some(<item>) = x` LL | // unnecessary LL | x.unwrap(); | ^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr index ddd600418af..f7e338935a7 100644 --- a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr +++ b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr @@ -2,7 +2,7 @@ error: called `unwrap` on `x` after checking its variant with `is_some` --> tests/ui/checked_unwrap/simple_conditionals.rs:46:9 | LL | if x.is_some() { - | -------------- help: try: `if let Some(..) = x` + | -------------- help: try: `if let Some(<item>) = x` LL | // unnecessary LL | x.unwrap(); | ^^^^^^^^^^ @@ -17,7 +17,7 @@ error: called `expect` on `x` after checking its variant with `is_some` --> tests/ui/checked_unwrap/simple_conditionals.rs:49:9 | LL | if x.is_some() { - | -------------- help: try: `if let Some(..) = x` + | -------------- help: try: `if let Some(<item>) = x` ... LL | x.expect("an error message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -59,7 +59,7 @@ error: called `unwrap` on `x` after checking its variant with `is_none` --> tests/ui/checked_unwrap/simple_conditionals.rs:65:9 | LL | if x.is_none() { - | -------------- help: try: `if let Some(..) = x` + | -------------- help: try: `if let Some(<item>) = x` ... LL | x.unwrap(); | ^^^^^^^^^^ @@ -68,7 +68,7 @@ error: called `unwrap` on `x` after checking its variant with `is_some` --> tests/ui/checked_unwrap/simple_conditionals.rs:13:13 | LL | if $a.is_some() { - | --------------- help: try: `if let Some(..) = x` + | --------------- help: try: `if let Some(<item>) = x` LL | // unnecessary LL | $a.unwrap(); | ^^^^^^^^^^^ @@ -82,7 +82,7 @@ error: called `unwrap` on `x` after checking its variant with `is_ok` --> tests/ui/checked_unwrap/simple_conditionals.rs:78:9 | LL | if x.is_ok() { - | ------------ help: try: `if let Ok(..) = x` + | ------------ help: try: `if let Ok(<item>) = x` LL | // unnecessary LL | x.unwrap(); | ^^^^^^^^^^ @@ -91,7 +91,7 @@ error: called `expect` on `x` after checking its variant with `is_ok` --> tests/ui/checked_unwrap/simple_conditionals.rs:81:9 | LL | if x.is_ok() { - | ------------ help: try: `if let Ok(..) = x` + | ------------ help: try: `if let Ok(<item>) = x` ... LL | x.expect("an error message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -127,7 +127,7 @@ error: called `unwrap_err` on `x` after checking its variant with `is_ok` --> tests/ui/checked_unwrap/simple_conditionals.rs:94:9 | LL | if x.is_ok() { - | ------------ help: try: `if let Err(..) = x` + | ------------ help: try: `if let Err(<item>) = x` ... LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ error: called `unwrap_err` on `x` after checking its variant with `is_err` --> tests/ui/checked_unwrap/simple_conditionals.rs:102:9 | LL | if x.is_err() { - | ------------- help: try: `if let Err(..) = x` + | ------------- help: try: `if let Err(<item>) = x` ... LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ @@ -154,7 +154,7 @@ error: called `unwrap` on `x` after checking its variant with `is_err` --> tests/ui/checked_unwrap/simple_conditionals.rs:106:9 | LL | if x.is_err() { - | ------------- help: try: `if let Ok(..) = x` + | ------------- help: try: `if let Ok(<item>) = x` ... LL | x.unwrap(); | ^^^^^^^^^^ @@ -172,7 +172,7 @@ error: called `unwrap` on `option` after checking its variant with `is_some` --> tests/ui/checked_unwrap/simple_conditionals.rs:134:9 | LL | if option.is_some() { - | ------------------- help: try: `if let Some(..) = &option` + | ------------------- help: try: `if let Some(<item>) = &option` LL | option.as_ref().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -189,7 +189,7 @@ error: called `unwrap` on `result` after checking its variant with `is_ok` --> tests/ui/checked_unwrap/simple_conditionals.rs:144:9 | LL | if result.is_ok() { - | ----------------- help: try: `if let Ok(..) = &result` + | ----------------- help: try: `if let Ok(<item>) = &result` LL | result.as_ref().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -206,7 +206,7 @@ error: called `unwrap` on `option` after checking its variant with `is_some` --> tests/ui/checked_unwrap/simple_conditionals.rs:153:9 | LL | if option.is_some() { - | ------------------- help: try: `if let Some(..) = &mut option` + | ------------------- help: try: `if let Some(<item>) = &mut option` LL | option.as_mut().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -223,7 +223,7 @@ error: called `unwrap` on `result` after checking its variant with `is_ok` --> tests/ui/checked_unwrap/simple_conditionals.rs:162:9 | LL | if result.is_ok() { - | ----------------- help: try: `if let Ok(..) = &mut result` + | ----------------- help: try: `if let Ok(<item>) = &mut result` LL | result.as_mut().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/collapsible_match.stderr b/src/tools/clippy/tests/ui/collapsible_match.stderr index 01944baee79..1da78b56239 100644 --- a/src/tools/clippy/tests/ui/collapsible_match.stderr +++ b/src/tools/clippy/tests/ui/collapsible_match.stderr @@ -223,7 +223,7 @@ help: the outer pattern can be modified to include the inner pattern LL | if let Issue9647::A { a, .. } = x { | ^ replace this binding LL | if let Some(u) = a { - | ^^^^^^^ with this pattern, prefixed by a: + | ^^^^^^^ with this pattern, prefixed by `a`: error: this `if let` can be collapsed into the outer `if let` --> tests/ui/collapsible_match.rs:292:9 diff --git a/src/tools/clippy/tests/ui/crashes/ice-3717.fixed b/src/tools/clippy/tests/ui/crashes/ice-3717.fixed new file mode 100644 index 00000000000..3f54b326979 --- /dev/null +++ b/src/tools/clippy/tests/ui/crashes/ice-3717.fixed @@ -0,0 +1,11 @@ +#![deny(clippy::implicit_hasher)] + +use std::collections::HashSet; + +fn main() {} + +pub fn ice_3717<S: ::std::hash::BuildHasher + Default>(_: &HashSet<usize, S>) { + //~^ ERROR: parameter of type `HashSet` should be generalized over different hashers + let _ = [0u8; 0]; + let _: HashSet<usize> = HashSet::default(); +} diff --git a/src/tools/clippy/tests/ui/crashes/ice-3717.rs b/src/tools/clippy/tests/ui/crashes/ice-3717.rs index 770f6cf448a..2890a9277c7 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-3717.rs +++ b/src/tools/clippy/tests/ui/crashes/ice-3717.rs @@ -1,7 +1,5 @@ #![deny(clippy::implicit_hasher)] -//@no-rustfix: need to change the suggestion to a multipart suggestion - use std::collections::HashSet; fn main() {} diff --git a/src/tools/clippy/tests/ui/crashes/ice-3717.stderr b/src/tools/clippy/tests/ui/crashes/ice-3717.stderr index 4b4618ee1bb..aac72c66965 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-3717.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-3717.stderr @@ -1,5 +1,5 @@ error: parameter of type `HashSet` should be generalized over different hashers - --> tests/ui/crashes/ice-3717.rs:9:21 + --> tests/ui/crashes/ice-3717.rs:7:21 | LL | pub fn ice_3717(_: &HashSet<usize>) { | ^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs index 56a8d22cb1c..9dafad8b784 100644 --- a/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs +++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs @@ -3,6 +3,7 @@ use std::borrow::Cow; use std::cell::Cell; use std::fmt::Display; +use std::ptr; use std::sync::atomic::AtomicUsize; use std::sync::Once; @@ -53,4 +54,20 @@ mod issue_8493 { issue_8493!(); } +#[repr(C, align(8))] +struct NoAtomic(usize); +#[repr(C, align(8))] +struct WithAtomic(AtomicUsize); + +const fn with_non_null() -> *const WithAtomic { + const NO_ATOMIC: NoAtomic = NoAtomic(0); + (&NO_ATOMIC as *const NoAtomic).cast() +} +const WITH_ATOMIC: *const WithAtomic = with_non_null(); + +struct Generic<T>(T); +impl<T> Generic<T> { + const RAW_POINTER: *const Cell<T> = ptr::null(); +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr index 1f2b9561ce5..4a725147142 100644 --- a/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr +++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr @@ -1,5 +1,5 @@ error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/others.rs:9:1 + --> tests/ui/declare_interior_mutable_const/others.rs:10:1 | LL | const ATOMIC: AtomicUsize = AtomicUsize::new(5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | const ATOMIC: AtomicUsize = AtomicUsize::new(5); = help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]` error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/others.rs:10:1 + --> tests/ui/declare_interior_mutable_const/others.rs:11:1 | LL | const CELL: Cell<usize> = Cell::new(6); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | const CELL: Cell<usize> = Cell::new(6); = help: consider making this `Sync` so that it can go in a static item or using a `thread_local` error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/others.rs:11:1 + --> tests/ui/declare_interior_mutable_const/others.rs:12:1 | LL | const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec<AtomicUsize>, u8) = ([ATOMIC], Vec::new(), 7); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec<AtomicUsize>, u8) = ([ATOMIC], V = help: consider making this a static item error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/others.rs:16:9 + --> tests/ui/declare_interior_mutable_const/others.rs:17:9 | LL | const $name: $ty = $e; | ^^^^^^^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | declare_const!(_ONCE: Once = Once::new()); = note: this error originates in the macro `declare_const` (in Nightly builds, run with -Z macro-backtrace for more info) error: a `const` item should not be interior mutable - --> tests/ui/declare_interior_mutable_const/others.rs:44:13 + --> tests/ui/declare_interior_mutable_const/others.rs:45:13 | LL | const _BAZ: Cell<usize> = Cell::new(0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.fixed b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.fixed new file mode 100644 index 00000000000..fb0f40b34a4 --- /dev/null +++ b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.fixed @@ -0,0 +1,13 @@ +// This test checks that words starting with capital letters and ending with "ified" don't +// trigger the lint. + +#![deny(clippy::doc_markdown)] + +pub enum OutputFormat { + /// `HumaNified` + //~^ ERROR: item in documentation is missing backticks + Plain, + // Should not warn! + /// JSONified console output + Json, +} diff --git a/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.rs b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.rs new file mode 100644 index 00000000000..8c1e1a3cd6c --- /dev/null +++ b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.rs @@ -0,0 +1,13 @@ +// This test checks that words starting with capital letters and ending with "ified" don't +// trigger the lint. + +#![deny(clippy::doc_markdown)] + +pub enum OutputFormat { + /// HumaNified + //~^ ERROR: item in documentation is missing backticks + Plain, + // Should not warn! + /// JSONified console output + Json, +} diff --git a/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr new file mode 100644 index 00000000000..ae68a767ec9 --- /dev/null +++ b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr @@ -0,0 +1,18 @@ +error: item in documentation is missing backticks + --> tests/ui/doc/doc_markdown-issue_13097.rs:7:9 + | +LL | /// HumaNified + | ^^^^^^^^^^ + | +note: the lint level is defined here + --> tests/ui/doc/doc_markdown-issue_13097.rs:4:9 + | +LL | #![deny(clippy::doc_markdown)] + | ^^^^^^^^^^^^^^^^^^^^ +help: try + | +LL | /// `HumaNified` + | ~~~~~~~~~~~~ + +error: aborting due to 1 previous error + diff --git a/src/tools/clippy/tests/ui/double_must_use.rs b/src/tools/clippy/tests/ui/double_must_use.rs index 615de3e2474..4460aeb075b 100644 --- a/src/tools/clippy/tests/ui/double_must_use.rs +++ b/src/tools/clippy/tests/ui/double_must_use.rs @@ -3,19 +3,19 @@ #[must_use] pub fn must_use_result() -> Result<(), ()> { - //~^ ERROR: this function has an empty `#[must_use]` attribute, but returns a type already + //~^ ERROR: this function has a `#[must_use]` attribute with no message, but returns a type already unimplemented!(); } #[must_use] pub fn must_use_tuple() -> (Result<(), ()>, u8) { - //~^ ERROR: this function has an empty `#[must_use]` attribute, but returns a type already + //~^ ERROR: this function has a `#[must_use]` attribute with no message, but returns a type already unimplemented!(); } #[must_use] pub fn must_use_array() -> [Result<(), ()>; 1] { - //~^ ERROR: this function has an empty `#[must_use]` attribute, but returns a type already + //~^ ERROR: this function has a `#[must_use]` attribute with no message, but returns a type already unimplemented!(); } @@ -32,7 +32,7 @@ async fn async_must_use() -> usize { #[must_use] async fn async_must_use_result() -> Result<(), ()> { - //~^ ERROR: this function has an empty `#[must_use]` attribute, but returns a type already + //~^ ERROR: this function has a `#[must_use]` attribute with no message, but returns a type already Ok(()) } diff --git a/src/tools/clippy/tests/ui/double_must_use.stderr b/src/tools/clippy/tests/ui/double_must_use.stderr index 0f2154ecbcf..b26d1e48a8b 100644 --- a/src/tools/clippy/tests/ui/double_must_use.stderr +++ b/src/tools/clippy/tests/ui/double_must_use.stderr @@ -1,36 +1,36 @@ -error: this function has an empty `#[must_use]` attribute, but returns a type already marked as `#[must_use]` +error: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]` --> tests/ui/double_must_use.rs:5:1 | LL | pub fn must_use_result() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: either add some descriptive text or remove the attribute + = help: either add some descriptive message or remove the attribute = note: `-D clippy::double-must-use` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::double_must_use)]` -error: this function has an empty `#[must_use]` attribute, but returns a type already marked as `#[must_use]` +error: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]` --> tests/ui/double_must_use.rs:11:1 | LL | pub fn must_use_tuple() -> (Result<(), ()>, u8) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: either add some descriptive text or remove the attribute + = help: either add some descriptive message or remove the attribute -error: this function has an empty `#[must_use]` attribute, but returns a type already marked as `#[must_use]` +error: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]` --> tests/ui/double_must_use.rs:17:1 | LL | pub fn must_use_array() -> [Result<(), ()>; 1] { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: either add some descriptive text or remove the attribute + = help: either add some descriptive message or remove the attribute -error: this function has an empty `#[must_use]` attribute, but returns a type already marked as `#[must_use]` +error: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]` --> tests/ui/double_must_use.rs:34:1 | LL | async fn async_must_use_result() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: either add some descriptive text or remove the attribute + = help: either add some descriptive message or remove the attribute error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.fixed b/src/tools/clippy/tests/ui/explicit_iter_loop.fixed index f38b34c5a7c..1148f0f6c6a 100644 --- a/src/tools/clippy/tests/ui/explicit_iter_loop.fixed +++ b/src/tools/clippy/tests/ui/explicit_iter_loop.fixed @@ -153,3 +153,15 @@ fn main() { let r = &x; for _ in r {} } + +#[clippy::msrv = "1.79"] +pub fn issue_13184() { + // https://github.com/rust-lang/rust-clippy/issues/13184 + // No need to fix, as IntoIterator for Box is valid starting from 1.80 + let mut values: Box<[u32]> = Box::new([1, 2]); + for _ in values.iter() {} + for _ in values.iter_mut() {} + + let rvalues = &values; + for _ in rvalues.iter() {} +} diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.rs b/src/tools/clippy/tests/ui/explicit_iter_loop.rs index 2e701ada5ac..4dda2f13e5b 100644 --- a/src/tools/clippy/tests/ui/explicit_iter_loop.rs +++ b/src/tools/clippy/tests/ui/explicit_iter_loop.rs @@ -153,3 +153,15 @@ fn main() { let r = &x; for _ in r.iter() {} } + +#[clippy::msrv = "1.79"] +pub fn issue_13184() { + // https://github.com/rust-lang/rust-clippy/issues/13184 + // No need to fix, as IntoIterator for Box is valid starting from 1.80 + let mut values: Box<[u32]> = Box::new([1, 2]); + for _ in values.iter() {} + for _ in values.iter_mut() {} + + let rvalues = &values; + for _ in rvalues.iter() {} +} diff --git a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed index 5778f8f526f..4c324587c96 100644 --- a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed +++ b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed @@ -15,6 +15,14 @@ struct Foo { z: i32, } +#[derive(Default)] +#[allow(clippy::inconsistent_struct_constructor)] +struct Bar { + x: i32, + y: i32, + z: i32, +} + mod without_base { use super::Foo; @@ -70,4 +78,17 @@ mod with_base { } } +mod with_allow_ty_def { + use super::Bar; + + fn test() { + let x = 1; + let y = 1; + let z = 1; + + // Should NOT lint because `Bar` is defined with `#[allow(clippy::inconsistent_struct_constructor)]` + Bar { y, x, z }; + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs index 9efaf068934..d49f236b9b0 100644 --- a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs +++ b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs @@ -15,6 +15,14 @@ struct Foo { z: i32, } +#[derive(Default)] +#[allow(clippy::inconsistent_struct_constructor)] +struct Bar { + x: i32, + y: i32, + z: i32, +} + mod without_base { use super::Foo; @@ -74,4 +82,17 @@ mod with_base { } } +mod with_allow_ty_def { + use super::Bar; + + fn test() { + let x = 1; + let y = 1; + let z = 1; + + // Should NOT lint because `Bar` is defined with `#[allow(clippy::inconsistent_struct_constructor)]` + Bar { y, x, z }; + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr index 1192271f911..97bb7c789a7 100644 --- a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr +++ b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr @@ -1,5 +1,5 @@ error: struct constructor field order is inconsistent with struct definition field order - --> tests/ui/inconsistent_struct_constructor.rs:28:9 + --> tests/ui/inconsistent_struct_constructor.rs:36:9 | LL | Foo { y, x, z }; | ^^^^^^^^^^^^^^^ help: try: `Foo { x, y, z }` @@ -8,7 +8,7 @@ LL | Foo { y, x, z }; = help: to override `-D warnings` add `#[allow(clippy::inconsistent_struct_constructor)]` error: struct constructor field order is inconsistent with struct definition field order - --> tests/ui/inconsistent_struct_constructor.rs:55:9 + --> tests/ui/inconsistent_struct_constructor.rs:63:9 | LL | / Foo { LL | | z, diff --git a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs index 2dccadd9fce..c8409d78ed7 100644 --- a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs +++ b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs @@ -17,7 +17,7 @@ mod multiple { //~^ ERROR: `clippy::msrv` is defined multiple times mod foo { - #![clippy::msrv = "1"] + #![clippy::msrv = "1.0"] #![clippy::msrv = "1.0.0"] //~^ ERROR: `clippy::msrv` is defined multiple times } diff --git a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr index b4cb1b5713f..dbc276ed89d 100644 --- a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr +++ b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr @@ -31,8 +31,8 @@ LL | #![clippy::msrv = "1.0.0"] note: first definition found here --> tests/ui/min_rust_version_invalid_attr.rs:20:9 | -LL | #![clippy::msrv = "1"] - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | #![clippy::msrv = "1.0"] + | ^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/string_slice.rs b/src/tools/clippy/tests/ui/string_slice.rs index 440a86b104a..1d1911aaa1d 100644 --- a/src/tools/clippy/tests/ui/string_slice.rs +++ b/src/tools/clippy/tests/ui/string_slice.rs @@ -1,3 +1,5 @@ +use std::borrow::Cow; + #[warn(clippy::string_slice)] #[allow(clippy::no_effect)] @@ -11,4 +13,7 @@ fn main() { let s = String::from(m); &s[0..2]; //~^ ERROR: indexing into a string may panic if the index is within a UTF-8 character + let a = Cow::Borrowed("foo"); + &a[0..3]; + //~^ ERROR: indexing into a string may panic if the index is within a UTF-8 character } diff --git a/src/tools/clippy/tests/ui/string_slice.stderr b/src/tools/clippy/tests/ui/string_slice.stderr index 7a4596b5f2d..bc0fcde34b8 100644 --- a/src/tools/clippy/tests/ui/string_slice.stderr +++ b/src/tools/clippy/tests/ui/string_slice.stderr @@ -1,5 +1,5 @@ error: indexing into a string may panic if the index is within a UTF-8 character - --> tests/ui/string_slice.rs:5:6 + --> tests/ui/string_slice.rs:7:6 | LL | &"Ölkanne"[1..]; | ^^^^^^^^^^^^^^ @@ -8,16 +8,22 @@ LL | &"Ölkanne"[1..]; = help: to override `-D warnings` add `#[allow(clippy::string_slice)]` error: indexing into a string may panic if the index is within a UTF-8 character - --> tests/ui/string_slice.rs:9:6 + --> tests/ui/string_slice.rs:11:6 | LL | &m[2..5]; | ^^^^^^^ error: indexing into a string may panic if the index is within a UTF-8 character - --> tests/ui/string_slice.rs:12:6 + --> tests/ui/string_slice.rs:14:6 | LL | &s[0..2]; | ^^^^^^^ -error: aborting due to 3 previous errors +error: indexing into a string may panic if the index is within a UTF-8 character + --> tests/ui/string_slice.rs:17:6 + | +LL | &a[0..3]; + | ^^^^^^^ + +error: aborting due to 4 previous errors diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.fixed b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.fixed new file mode 100644 index 00000000000..d4a0cdf3447 --- /dev/null +++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.fixed @@ -0,0 +1,9 @@ +#![warn(clippy::too_long_first_doc_paragraph)] + +/// A very short summary. +/// +/// A much longer explanation that goes into a lot more detail about +/// how the thing works, possibly with doclinks and so one, +/// and probably spanning a many rows. Blablabla, it needs to be over +/// 200 characters so I needed to write something longeeeeeeer. +pub struct Foo; diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.rs b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.rs new file mode 100644 index 00000000000..5a3b6c42a32 --- /dev/null +++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.rs @@ -0,0 +1,8 @@ +#![warn(clippy::too_long_first_doc_paragraph)] + +/// A very short summary. +/// A much longer explanation that goes into a lot more detail about +/// how the thing works, possibly with doclinks and so one, +/// and probably spanning a many rows. Blablabla, it needs to be over +/// 200 characters so I needed to write something longeeeeeeer. +pub struct Foo; diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr new file mode 100644 index 00000000000..6403265a39c --- /dev/null +++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr @@ -0,0 +1,20 @@ +error: first doc comment paragraph is too long + --> tests/ui/too_long_first_doc_paragraph-fix.rs:3:1 + | +LL | / /// A very short summary. +LL | | /// A much longer explanation that goes into a lot more detail about +LL | | /// how the thing works, possibly with doclinks and so one, +LL | | /// and probably spanning a many rows. Blablabla, it needs to be over +LL | | /// 200 characters so I needed to write something longeeeeeeer. + | |_ + | + = note: `-D clippy::too-long-first-doc-paragraph` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::too_long_first_doc_paragraph)]` +help: add an empty line + | +LL ~ /// A very short summary. +LL + /// + | + +error: aborting due to 1 previous error + diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.rs b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.rs new file mode 100644 index 00000000000..1042249c5b7 --- /dev/null +++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.rs @@ -0,0 +1,53 @@ +//@no-rustfix + +#![warn(clippy::too_long_first_doc_paragraph)] + +/// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia +/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero, +/// gravida non lacinia at, rhoncus eu lacus. +pub struct Bar; + +// Should not warn! (not an item visible on mod page) +/// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia +/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero, +/// gravida non lacinia at, rhoncus eu lacus. +impl Bar {} + +// Should not warn! (less than 80 characters) +/// Lorem ipsum dolor sit amet, consectetur adipiscing elit. +/// +/// Nunc turpis nunc, lacinia +/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero, +/// gravida non lacinia at, rhoncus eu lacus. +pub enum Enum { + A, +} + +/// Lorem +/// ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia +/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero, +/// gravida non lacinia at, rhoncus eu lacus. +pub union Union { + a: u8, + b: u8, +} + +// Should not warn! (title) +/// # bla +/// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia +/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero, +/// gravida non lacinia at, rhoncus eu lacus. +pub union Union2 { + a: u8, + b: u8, +} + +// Should not warn! (not public) +/// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia +/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero, +/// gravida non lacinia at, rhoncus eu lacus. +fn f() {} + +fn main() { + // test code goes here +} diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr new file mode 100644 index 00000000000..7f48e5cf884 --- /dev/null +++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr @@ -0,0 +1,22 @@ +error: first doc comment paragraph is too long + --> tests/ui/too_long_first_doc_paragraph.rs:5:1 + | +LL | / /// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia +LL | | /// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero, +LL | | /// gravida non lacinia at, rhoncus eu lacus. + | |_ + | + = note: `-D clippy::too-long-first-doc-paragraph` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::too_long_first_doc_paragraph)]` + +error: first doc comment paragraph is too long + --> tests/ui/too_long_first_doc_paragraph.rs:26:1 + | +LL | / /// Lorem +LL | | /// ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia +LL | | /// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero, +LL | | /// gravida non lacinia at, rhoncus eu lacus. + | |_ + +error: aborting due to 2 previous errors + diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr index fcd60f48bcc..bcdf65b217e 100644 --- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr @@ -2,316 +2,432 @@ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:83:13 | LL | let _ = opt.unwrap_or_else(|| 2); - | ^^^^-------------------- - | | - | help: use `unwrap_or(..)` instead: `unwrap_or(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::unnecessary-lazy-evaluations` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_lazy_evaluations)]` +help: use `unwrap_or` instead + | +LL | let _ = opt.unwrap_or(2); + | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:84:13 | LL | let _ = opt.unwrap_or_else(|| astronomers_pi); - | ^^^^--------------------------------- - | | - | help: use `unwrap_or(..)` instead: `unwrap_or(astronomers_pi)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `unwrap_or` instead + | +LL | let _ = opt.unwrap_or(astronomers_pi); + | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:85:13 | LL | let _ = opt.unwrap_or_else(|| ext_str.some_field); - | ^^^^------------------------------------- - | | - | help: use `unwrap_or(..)` instead: `unwrap_or(ext_str.some_field)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `unwrap_or` instead + | +LL | let _ = opt.unwrap_or(ext_str.some_field); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:87:13 | LL | let _ = opt.and_then(|_| ext_opt); - | ^^^^--------------------- - | | - | help: use `and(..)` instead: `and(ext_opt)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `and` instead + | +LL | let _ = opt.and(ext_opt); + | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:88:13 | LL | let _ = opt.or_else(|| ext_opt); - | ^^^^------------------- - | | - | help: use `or(..)` instead: `or(ext_opt)` + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `or` instead + | +LL | let _ = opt.or(ext_opt); + | ~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:89:13 | LL | let _ = opt.or_else(|| None); - | ^^^^---------------- - | | - | help: use `or(..)` instead: `or(None)` + | ^^^^^^^^^^^^^^^^^^^^ + | +help: use `or` instead + | +LL | let _ = opt.or(None); + | ~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:90:13 | LL | let _ = opt.get_or_insert_with(|| 2); - | ^^^^------------------------ - | | - | help: use `get_or_insert(..)` instead: `get_or_insert(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `get_or_insert` instead + | +LL | let _ = opt.get_or_insert(2); + | ~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:91:13 | LL | let _ = opt.ok_or_else(|| 2); - | ^^^^---------------- - | | - | help: use `ok_or(..)` instead: `ok_or(2)` + | ^^^^^^^^^^^^^^^^^^^^ + | +help: use `ok_or` instead + | +LL | let _ = opt.ok_or(2); + | ~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:92:13 | LL | let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2))); - | ^^^^^^^^^^^^^^^^^------------------------------- - | | - | help: use `unwrap_or(..)` instead: `unwrap_or(Some((1, 2)))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `unwrap_or` instead + | +LL | let _ = nested_tuple_opt.unwrap_or(Some((1, 2))); + | ~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:93:13 | LL | let _ = cond.then(|| astronomers_pi); - | ^^^^^----------------------- - | | - | help: use `then_some(..)` instead: `then_some(astronomers_pi)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _ = cond.then_some(astronomers_pi); + | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:94:13 | LL | let _ = true.then(|| -> _ {}); - | ^^^^^---------------- - | | - | help: use `then_some(..)` instead: `then_some({})` + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _ = true.then_some({}); + | ~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:95:13 | LL | let _ = true.then(|| {}); - | ^^^^^----------- - | | - | help: use `then_some(..)` instead: `then_some({})` + | ^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _ = true.then_some({}); + | ~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:99:13 | LL | let _ = Some(1).unwrap_or_else(|| *r); - | ^^^^^^^^--------------------- - | | - | help: use `unwrap_or(..)` instead: `unwrap_or(*r)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `unwrap_or` instead + | +LL | let _ = Some(1).unwrap_or(*r); + | ~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:101:13 | LL | let _ = Some(1).unwrap_or_else(|| *b); - | ^^^^^^^^--------------------- - | | - | help: use `unwrap_or(..)` instead: `unwrap_or(*b)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `unwrap_or` instead + | +LL | let _ = Some(1).unwrap_or(*b); + | ~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:103:13 | LL | let _ = Some(1).as_ref().unwrap_or_else(|| &r); - | ^^^^^^^^^^^^^^^^^--------------------- - | | - | help: use `unwrap_or(..)` instead: `unwrap_or(&r)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `unwrap_or` instead + | +LL | let _ = Some(1).as_ref().unwrap_or(&r); + | ~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:104:13 | LL | let _ = Some(1).as_ref().unwrap_or_else(|| &b); - | ^^^^^^^^^^^^^^^^^--------------------- - | | - | help: use `unwrap_or(..)` instead: `unwrap_or(&b)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `unwrap_or` instead + | +LL | let _ = Some(1).as_ref().unwrap_or(&b); + | ~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:107:13 | LL | let _ = Some(10).unwrap_or_else(|| 2); - | ^^^^^^^^^-------------------- - | | - | help: use `unwrap_or(..)` instead: `unwrap_or(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `unwrap_or` instead + | +LL | let _ = Some(10).unwrap_or(2); + | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:108:13 | LL | let _ = Some(10).and_then(|_| ext_opt); - | ^^^^^^^^^--------------------- - | | - | help: use `and(..)` instead: `and(ext_opt)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `and` instead + | +LL | let _ = Some(10).and(ext_opt); + | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:109:28 | LL | let _: Option<usize> = None.or_else(|| ext_opt); - | ^^^^^------------------- - | | - | help: use `or(..)` instead: `or(ext_opt)` + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `or` instead + | +LL | let _: Option<usize> = None.or(ext_opt); + | ~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:110:13 | LL | let _ = None.get_or_insert_with(|| 2); - | ^^^^^------------------------ - | | - | help: use `get_or_insert(..)` instead: `get_or_insert(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `get_or_insert` instead + | +LL | let _ = None.get_or_insert(2); + | ~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:111:35 | LL | let _: Result<usize, usize> = None.ok_or_else(|| 2); - | ^^^^^---------------- - | | - | help: use `ok_or(..)` instead: `ok_or(2)` + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use `ok_or` instead + | +LL | let _: Result<usize, usize> = None.ok_or(2); + | ~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:112:28 | LL | let _: Option<usize> = None.or_else(|| None); - | ^^^^^---------------- - | | - | help: use `or(..)` instead: `or(None)` + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use `or` instead + | +LL | let _: Option<usize> = None.or(None); + | ~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:115:13 | LL | let _ = deep.0.unwrap_or_else(|| 2); - | ^^^^^^^-------------------- - | | - | help: use `unwrap_or(..)` instead: `unwrap_or(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `unwrap_or` instead + | +LL | let _ = deep.0.unwrap_or(2); + | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:116:13 | LL | let _ = deep.0.and_then(|_| ext_opt); - | ^^^^^^^--------------------- - | | - | help: use `and(..)` instead: `and(ext_opt)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `and` instead + | +LL | let _ = deep.0.and(ext_opt); + | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:117:13 | LL | let _ = deep.0.or_else(|| None); - | ^^^^^^^---------------- - | | - | help: use `or(..)` instead: `or(None)` + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `or` instead + | +LL | let _ = deep.0.or(None); + | ~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:118:13 | LL | let _ = deep.0.get_or_insert_with(|| 2); - | ^^^^^^^------------------------ - | | - | help: use `get_or_insert(..)` instead: `get_or_insert(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `get_or_insert` instead + | +LL | let _ = deep.0.get_or_insert(2); + | ~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:119:13 | LL | let _ = deep.0.ok_or_else(|| 2); - | ^^^^^^^---------------- - | | - | help: use `ok_or(..)` instead: `ok_or(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `ok_or` instead + | +LL | let _ = deep.0.ok_or(2); + | ~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:150:28 | LL | let _: Option<usize> = None.or_else(|| Some(3)); - | ^^^^^------------------- - | | - | help: use `or(..)` instead: `or(Some(3))` + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `or` instead + | +LL | let _: Option<usize> = None.or(Some(3)); + | ~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:151:13 | LL | let _ = deep.0.or_else(|| Some(3)); - | ^^^^^^^------------------- - | | - | help: use `or(..)` instead: `or(Some(3))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `or` instead + | +LL | let _ = deep.0.or(Some(3)); + | ~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Option::None` --> tests/ui/unnecessary_lazy_eval.rs:152:13 | LL | let _ = opt.or_else(|| Some(3)); - | ^^^^------------------- - | | - | help: use `or(..)` instead: `or(Some(3))` + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `or` instead + | +LL | let _ = opt.or(Some(3)); + | ~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:158:13 | LL | let _ = res2.unwrap_or_else(|_| 2); - | ^^^^^--------------------- - | | - | help: use `unwrap_or(..)` instead: `unwrap_or(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `unwrap_or` instead + | +LL | let _ = res2.unwrap_or(2); + | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:159:13 | LL | let _ = res2.unwrap_or_else(|_| astronomers_pi); - | ^^^^^---------------------------------- - | | - | help: use `unwrap_or(..)` instead: `unwrap_or(astronomers_pi)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `unwrap_or` instead + | +LL | let _ = res2.unwrap_or(astronomers_pi); + | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:160:13 | LL | let _ = res2.unwrap_or_else(|_| ext_str.some_field); - | ^^^^^-------------------------------------- - | | - | help: use `unwrap_or(..)` instead: `unwrap_or(ext_str.some_field)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `unwrap_or` instead + | +LL | let _ = res2.unwrap_or(ext_str.some_field); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:182:35 | LL | let _: Result<usize, usize> = res.and_then(|_| Err(2)); - | ^^^^-------------------- - | | - | help: use `and(..)` instead: `and(Err(2))` + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `and` instead + | +LL | let _: Result<usize, usize> = res.and(Err(2)); + | ~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:183:35 | LL | let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi)); - | ^^^^--------------------------------- - | | - | help: use `and(..)` instead: `and(Err(astronomers_pi))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `and` instead + | +LL | let _: Result<usize, usize> = res.and(Err(astronomers_pi)); + | ~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:184:35 | LL | let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field)); - | ^^^^------------------------------------- - | | - | help: use `and(..)` instead: `and(Err(ext_str.some_field))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `and` instead + | +LL | let _: Result<usize, usize> = res.and(Err(ext_str.some_field)); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:186:35 | LL | let _: Result<usize, usize> = res.or_else(|_| Ok(2)); - | ^^^^------------------ - | | - | help: use `or(..)` instead: `or(Ok(2))` + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `or` instead + | +LL | let _: Result<usize, usize> = res.or(Ok(2)); + | ~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:187:35 | LL | let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi)); - | ^^^^------------------------------- - | | - | help: use `or(..)` instead: `or(Ok(astronomers_pi))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `or` instead + | +LL | let _: Result<usize, usize> = res.or(Ok(astronomers_pi)); + | ~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:188:35 | LL | let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field)); - | ^^^^----------------------------------- - | | - | help: use `or(..)` instead: `or(Ok(ext_str.some_field))` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `or` instead + | +LL | let _: Result<usize, usize> = res.or(Ok(ext_str.some_field)); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval.rs:189:35 @@ -324,193 +440,265 @@ LL | | // some lines ... | LL | | // some lines LL | | or_else(|_| Ok(ext_str.some_field)); - | |_____----------------------------------^ - | | - | help: use `or(..)` instead: `or(Ok(ext_str.some_field))` + | |_______________________________________^ + | +help: use `or` instead + | +LL | or(Ok(ext_str.some_field)); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:219:14 | LL | let _x = false.then(|| i32::MAX + 1); - | ^^^^^^--------------------- - | | - | help: use `then_some(..)` instead: `then_some(i32::MAX + 1)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(i32::MAX + 1); + | ~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:221:14 | LL | let _x = false.then(|| i32::MAX * 2); - | ^^^^^^--------------------- - | | - | help: use `then_some(..)` instead: `then_some(i32::MAX * 2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(i32::MAX * 2); + | ~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:223:14 | LL | let _x = false.then(|| i32::MAX - 1); - | ^^^^^^--------------------- - | | - | help: use `then_some(..)` instead: `then_some(i32::MAX - 1)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(i32::MAX - 1); + | ~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:225:14 | LL | let _x = false.then(|| i32::MIN - 1); - | ^^^^^^--------------------- - | | - | help: use `then_some(..)` instead: `then_some(i32::MIN - 1)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(i32::MIN - 1); + | ~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:227:14 | LL | let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2); - | ^^^^^^------------------------------------- - | | - | help: use `then_some(..)` instead: `then_some((1 + 2 * 3 - 2 / 3 + 9) << 2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some((1 + 2 * 3 - 2 / 3 + 9) << 2); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:229:14 | LL | let _x = false.then(|| 255u8 << 7); - | ^^^^^^------------------- - | | - | help: use `then_some(..)` instead: `then_some(255u8 << 7)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(255u8 << 7); + | ~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:231:14 | LL | let _x = false.then(|| 255u8 << 8); - | ^^^^^^------------------- - | | - | help: use `then_some(..)` instead: `then_some(255u8 << 8)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(255u8 << 8); + | ~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:233:14 | LL | let _x = false.then(|| 255u8 >> 8); - | ^^^^^^------------------- - | | - | help: use `then_some(..)` instead: `then_some(255u8 >> 8)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(255u8 >> 8); + | ~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:236:14 | LL | let _x = false.then(|| i32::MAX + -1); - | ^^^^^^---------------------- - | | - | help: use `then_some(..)` instead: `then_some(i32::MAX + -1)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(i32::MAX + -1); + | ~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:238:14 | LL | let _x = false.then(|| -i32::MAX); - | ^^^^^^------------------ - | | - | help: use `then_some(..)` instead: `then_some(-i32::MAX)` + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(-i32::MAX); + | ~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:240:14 | LL | let _x = false.then(|| -i32::MIN); - | ^^^^^^------------------ - | | - | help: use `then_some(..)` instead: `then_some(-i32::MIN)` + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(-i32::MIN); + | ~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:243:14 | LL | let _x = false.then(|| 255 >> -7); - | ^^^^^^------------------ - | | - | help: use `then_some(..)` instead: `then_some(255 >> -7)` + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(255 >> -7); + | ~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:245:14 | LL | let _x = false.then(|| 255 << -1); - | ^^^^^^------------------ - | | - | help: use `then_some(..)` instead: `then_some(255 << -1)` + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(255 << -1); + | ~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:247:14 | LL | let _x = false.then(|| 1 / 0); - | ^^^^^^-------------- - | | - | help: use `then_some(..)` instead: `then_some(1 / 0)` + | ^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(1 / 0); + | ~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:249:14 | LL | let _x = false.then(|| x << -1); - | ^^^^^^---------------- - | | - | help: use `then_some(..)` instead: `then_some(x << -1)` + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(x << -1); + | ~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:251:14 | LL | let _x = false.then(|| x << 2); - | ^^^^^^--------------- - | | - | help: use `then_some(..)` instead: `then_some(x << 2)` + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(x << 2); + | ~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:261:14 | LL | let _x = false.then(|| x / 0); - | ^^^^^^-------------- - | | - | help: use `then_some(..)` instead: `then_some(x / 0)` + | ^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(x / 0); + | ~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:263:14 | LL | let _x = false.then(|| x % 0); - | ^^^^^^-------------- - | | - | help: use `then_some(..)` instead: `then_some(x % 0)` + | ^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(x % 0); + | ~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:266:14 | LL | let _x = false.then(|| 1 / -1); - | ^^^^^^--------------- - | | - | help: use `then_some(..)` instead: `then_some(1 / -1)` + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(1 / -1); + | ~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:268:14 | LL | let _x = false.then(|| i32::MIN / -1); - | ^^^^^^---------------------- - | | - | help: use `then_some(..)` instead: `then_some(i32::MIN / -1)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(i32::MIN / -1); + | ~~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:271:14 | LL | let _x = false.then(|| i32::MIN / 0); - | ^^^^^^--------------------- - | | - | help: use `then_some(..)` instead: `then_some(i32::MIN / 0)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(i32::MIN / 0); + | ~~~~~~~~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:273:14 | LL | let _x = false.then(|| 4 / 2); - | ^^^^^^-------------- - | | - | help: use `then_some(..)` instead: `then_some(4 / 2)` + | ^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(4 / 2); + | ~~~~~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval.rs:281:14 | LL | let _x = false.then(|| f1 + f2); - | ^^^^^^---------------- - | | - | help: use `then_some(..)` instead: `then_some(f1 + f2)` + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _x = false.then_some(f1 + f2); + | ~~~~~~~~~~~~~~~~~~ error: aborting due to 63 previous errors diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr index b566b119571..390235b2124 100644 --- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr @@ -2,36 +2,47 @@ error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval_unfixable.rs:13:13 | LL | let _ = Ok(1).unwrap_or_else(|()| 2); - | ^^^^^^---------------------- - | | - | help: use `unwrap_or(..)` instead: `unwrap_or(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::unnecessary-lazy-evaluations` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_lazy_evaluations)]` +help: use `unwrap_or` instead + | +LL | let _ = Ok(1).unwrap_or(2); + | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval_unfixable.rs:19:13 | LL | let _ = Ok(1).unwrap_or_else(|e::E| 2); - | ^^^^^^------------------------ - | | - | help: use `unwrap_or(..)` instead: `unwrap_or(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `unwrap_or` instead + | +LL | let _ = Ok(1).unwrap_or(2); + | ~~~~~~~~~~~~ error: unnecessary closure used to substitute value for `Result::Err` --> tests/ui/unnecessary_lazy_eval_unfixable.rs:21:13 | LL | let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2); - | ^^^^^^------------------------------------- - | | - | help: use `unwrap_or(..)` instead: `unwrap_or(2)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `unwrap_or` instead + | +LL | let _ = Ok(1).unwrap_or(2); + | ~~~~~~~~~~~~ error: unnecessary closure used with `bool::then` --> tests/ui/unnecessary_lazy_eval_unfixable.rs:31:13 | LL | let _ = true.then(|| -> &[u8] { &[] }); - | ^^^^^------------------------- - | | - | help: use `then_some(..)` instead: `then_some({ &[] })` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `then_some` instead + | +LL | let _ = true.then_some({ &[] }); + | ~~~~~~~~~~~~~~~~~~ error: aborting due to 4 previous errors |
