diff --git a/clippy_dev/src/lib.rs b/clippy_dev/src/lib.rs index 83f60f15906f..1f8510f43a61 100644 --- a/clippy_dev/src/lib.rs +++ b/clippy_dev/src/lib.rs @@ -62,110 +62,89 @@ impl Lint { } /// Returns all non-deprecated lints and non-internal lints - pub fn usable_lints(lints: impl Iterator) -> impl Iterator { - lints.filter(|l| l.deprecation.is_none() && !l.is_internal()) + #[must_use] + pub fn usable_lints(lints: &[Self]) -> Vec { + lints + .iter() + .filter(|l| l.deprecation.is_none() && !l.group.starts_with("internal")) + .cloned() + .collect() } /// Returns all internal lints (not `internal_warn` lints) - pub fn internal_lints(lints: impl Iterator) -> impl Iterator { - lints.filter(|l| l.group == "internal") + #[must_use] + pub fn internal_lints(lints: &[Self]) -> Vec { + lints.iter().filter(|l| l.group == "internal").cloned().collect() } - /// Returns the lints in a `HashMap`, grouped by the different lint groups + /// Returns all deprecated lints #[must_use] - pub fn by_lint_group(lints: impl Iterator) -> HashMap> { - lints.map(|lint| (lint.group.to_string(), lint)).into_group_map() + pub fn deprecated_lints(lints: &[Self]) -> Vec { + lints.iter().filter(|l| l.deprecation.is_some()).cloned().collect() } + /// Returns the lints in a `HashMap`, grouped by the different lint groups #[must_use] - pub fn is_internal(&self) -> bool { - self.group.starts_with("internal") + pub fn by_lint_group(lints: impl Iterator) -> HashMap> { + lints.map(|lint| (lint.group.to_string(), lint)).into_group_map() } } /// Generates the Vec items for `register_lint_group` calls in `clippy_lints/src/lib.rs`. #[must_use] -pub fn gen_lint_group_list(lints: Vec) -> Vec { +pub fn gen_lint_group_list<'a>(lints: impl Iterator) -> Vec { lints - .into_iter() - .filter_map(|l| { - if l.deprecation.is_some() { - None - } else { - Some(format!(" LintId::of(&{}::{}),", l.module, l.name.to_uppercase())) - } - }) + .map(|l| format!(" LintId::of(&{}::{}),", l.module, l.name.to_uppercase())) .sorted() .collect::>() } /// Generates the `pub mod module_name` list in `clippy_lints/src/lib.rs`. #[must_use] -pub fn gen_modules_list(lints: Vec) -> Vec { +pub fn gen_modules_list<'a>(lints: impl Iterator) -> Vec { lints - .into_iter() - .filter_map(|l| { - if l.is_internal() || l.deprecation.is_some() { - None - } else { - Some(l.module) - } - }) + .map(|l| &l.module) .unique() - .map(|module| format!("pub mod {};", module)) + .map(|module| format!("mod {};", module)) .sorted() .collect::>() } /// Generates the list of lint links at the bottom of the README #[must_use] -pub fn gen_changelog_lint_list(lints: Vec) -> Vec { - let mut lint_list_sorted: Vec = lints; - lint_list_sorted.sort_by_key(|l| l.name.clone()); - lint_list_sorted - .iter() - .filter_map(|l| { - if l.is_internal() { - None - } else { - Some(format!("[`{}`]: {}#{}", l.name, DOCS_LINK, l.name)) - } - }) +pub fn gen_changelog_lint_list<'a>(lints: impl Iterator) -> Vec { + lints + .sorted_by_key(|l| &l.name) + .map(|l| format!("[`{}`]: {}#{}", l.name, DOCS_LINK, l.name)) .collect() } /// Generates the `register_removed` code in `./clippy_lints/src/lib.rs`. #[must_use] -pub fn gen_deprecated(lints: &[Lint]) -> Vec { +pub fn gen_deprecated<'a>(lints: impl Iterator) -> Vec { lints - .iter() - .filter_map(|l| { - l.clone().deprecation.map(|depr_text| { - vec![ - " store.register_removed(".to_string(), - format!(" \"clippy::{}\",", l.name), - format!(" \"{}\",", depr_text), - " );".to_string(), - ] - }) + .flat_map(|l| { + l.deprecation + .clone() + .map(|depr_text| { + vec![ + " store.register_removed(".to_string(), + format!(" \"clippy::{}\",", l.name), + format!(" \"{}\",", depr_text), + " );".to_string(), + ] + }) + .expect("only deprecated lints should be passed") }) - .flatten() .collect::>() } #[must_use] -pub fn gen_register_lint_list(lints: &[Lint]) -> Vec { +pub fn gen_register_lint_list<'a>(lints: impl Iterator) -> Vec { let pre = " store.register_lints(&[".to_string(); let post = " ]);".to_string(); let mut inner = lints - .iter() - .filter_map(|l| { - if !l.is_internal() && l.deprecation.is_none() { - Some(format!(" &{}::{},", l.module, l.name.to_uppercase())) - } else { - None - } - }) + .map(|l| format!(" &{}::{},", l.module, l.name.to_uppercase())) .sorted() .collect::>(); inner.insert(0, pre); @@ -439,7 +418,7 @@ fn test_usable_lints() { None, "module_name", )]; - assert_eq!(expected, Lint::usable_lints(lints.into_iter()).collect::>()); + assert_eq!(expected, Lint::usable_lints(&lints)); } #[test] @@ -469,13 +448,12 @@ fn test_gen_changelog_lint_list() { let lints = vec![ Lint::new("should_assert_eq", "group1", "abc", None, "module_name"), Lint::new("should_assert_eq2", "group2", "abc", None, "module_name"), - Lint::new("incorrect_internal", "internal_style", "abc", None, "module_name"), ]; let expected = vec![ format!("[`should_assert_eq`]: {}#should_assert_eq", DOCS_LINK.to_string()), format!("[`should_assert_eq2`]: {}#should_assert_eq2", DOCS_LINK.to_string()), ]; - assert_eq!(expected, gen_changelog_lint_list(lints)); + assert_eq!(expected, gen_changelog_lint_list(lints.iter())); } #[test] @@ -495,7 +473,6 @@ fn test_gen_deprecated() { Some("will be removed"), "module_name", ), - Lint::new("should_assert_eq2", "group2", "abc", None, "module_name"), ]; let expected: Vec = vec![ " store.register_removed(", @@ -510,22 +487,24 @@ fn test_gen_deprecated() { .into_iter() .map(String::from) .collect(); - assert_eq!(expected, gen_deprecated(&lints)); + assert_eq!(expected, gen_deprecated(lints.iter())); +} + +#[test] +#[should_panic] +fn test_gen_deprecated_fail() { + let lints = vec![Lint::new("should_assert_eq2", "group2", "abc", None, "module_name")]; + let _ = gen_deprecated(lints.iter()); } #[test] fn test_gen_modules_list() { let lints = vec![ Lint::new("should_assert_eq", "group1", "abc", None, "module_name"), - Lint::new("should_assert_eq2", "group2", "abc", Some("abc"), "deprecated"), Lint::new("incorrect_stuff", "group3", "abc", None, "another_module"), - Lint::new("incorrect_internal", "internal_style", "abc", None, "module_name"), - ]; - let expected = vec![ - "pub mod another_module;".to_string(), - "pub mod module_name;".to_string(), ]; - assert_eq!(expected, gen_modules_list(lints)); + let expected = vec!["mod another_module;".to_string(), "mod module_name;".to_string()]; + assert_eq!(expected, gen_modules_list(lints.iter())); } #[test] @@ -533,7 +512,6 @@ fn test_gen_lint_group_list() { let lints = vec![ Lint::new("abc", "group1", "abc", None, "module_name"), Lint::new("should_assert_eq", "group1", "abc", None, "module_name"), - Lint::new("should_assert_eq2", "group2", "abc", Some("abc"), "deprecated"), Lint::new("internal", "internal_style", "abc", None, "module_name"), ]; let expected = vec![ @@ -541,5 +519,5 @@ fn test_gen_lint_group_list() { " LintId::of(&module_name::INTERNAL),".to_string(), " LintId::of(&module_name::SHOULD_ASSERT_EQ),".to_string(), ]; - assert_eq!(expected, gen_lint_group_list(lints)); + assert_eq!(expected, gen_lint_group_list(lints.iter())); } diff --git a/clippy_dev/src/update_lints.rs b/clippy_dev/src/update_lints.rs index d30d6f97a2f7..a9a709299426 100644 --- a/clippy_dev/src/update_lints.rs +++ b/clippy_dev/src/update_lints.rs @@ -14,14 +14,14 @@ pub enum UpdateMode { pub fn run(update_mode: UpdateMode) { let lint_list: Vec = gather_all().collect(); - let internal_lints = Lint::internal_lints(lint_list.clone().into_iter()); - - let usable_lints: Vec = Lint::usable_lints(lint_list.clone().into_iter()).collect(); - let usable_lint_count = round_to_fifty(usable_lints.len()); - + let internal_lints = Lint::internal_lints(&lint_list); + let deprecated_lints = Lint::deprecated_lints(&lint_list); + let usable_lints = Lint::usable_lints(&lint_list); let mut sorted_usable_lints = usable_lints.clone(); sorted_usable_lints.sort_by_key(|lint| lint.name.clone()); + let usable_lint_count = round_to_fifty(usable_lints.len()); + let mut file_change = replace_region_in_file( Path::new("src/lintlist/mod.rs"), "begin lint list", @@ -61,7 +61,7 @@ pub fn run(update_mode: UpdateMode) { "", false, update_mode == UpdateMode::Change, - || gen_changelog_lint_list(lint_list.clone()), + || gen_changelog_lint_list(usable_lints.iter().chain(deprecated_lints.iter())), ) .changed; @@ -71,7 +71,7 @@ pub fn run(update_mode: UpdateMode) { "end deprecated lints", false, update_mode == UpdateMode::Change, - || gen_deprecated(&lint_list), + || gen_deprecated(deprecated_lints.iter()), ) .changed; @@ -81,7 +81,7 @@ pub fn run(update_mode: UpdateMode) { "end register lints", false, update_mode == UpdateMode::Change, - || gen_register_lint_list(&lint_list), + || gen_register_lint_list(usable_lints.iter().chain(internal_lints.iter())), ) .changed; @@ -91,7 +91,7 @@ pub fn run(update_mode: UpdateMode) { "end lints modules", false, update_mode == UpdateMode::Change, - || gen_modules_list(lint_list.clone()), + || gen_modules_list(usable_lints.iter()), ) .changed; @@ -104,13 +104,9 @@ pub fn run(update_mode: UpdateMode) { update_mode == UpdateMode::Change, || { // clippy::all should only include the following lint groups: - let all_group_lints = usable_lints - .clone() - .into_iter() - .filter(|l| { - l.group == "correctness" || l.group == "style" || l.group == "complexity" || l.group == "perf" - }) - .collect(); + let all_group_lints = usable_lints.iter().filter(|l| { + l.group == "correctness" || l.group == "style" || l.group == "complexity" || l.group == "perf" + }); gen_lint_group_list(all_group_lints) }, @@ -125,7 +121,7 @@ pub fn run(update_mode: UpdateMode) { r#"\]\);"#, false, update_mode == UpdateMode::Change, - || gen_lint_group_list(lints.clone()), + || gen_lint_group_list(lints.iter()), ) .changed; } @@ -140,8 +136,8 @@ pub fn run(update_mode: UpdateMode) { } pub fn print_lints() { - let lint_list = gather_all(); - let usable_lints: Vec = Lint::usable_lints(lint_list).collect(); + let lint_list: Vec = gather_all().collect(); + let usable_lints = Lint::usable_lints(&lint_list); let usable_lint_count = usable_lints.len(); let grouped_by_lint_group = Lint::by_lint_group(usable_lints.into_iter()); diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index dfc2a26b06b2..b24110fc1844 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -170,157 +170,157 @@ mod consts; mod utils; // begin lints modules, do not remove this comment, it’s used in `update_lints` -pub mod approx_const; -pub mod arithmetic; -pub mod as_conversions; -pub mod assertions_on_constants; -pub mod assign_ops; -pub mod atomic_ordering; -pub mod attrs; -pub mod bit_mask; -pub mod blacklisted_name; -pub mod block_in_if_condition; -pub mod booleans; -pub mod bytecount; -pub mod cargo_common_metadata; -pub mod checked_conversions; -pub mod cognitive_complexity; -pub mod collapsible_if; -pub mod comparison_chain; -pub mod copies; -pub mod copy_iterator; -pub mod dbg_macro; -pub mod default_trait_access; -pub mod derive; -pub mod doc; -pub mod double_comparison; -pub mod double_parens; -pub mod drop_bounds; -pub mod drop_forget_ref; -pub mod duration_subsec; -pub mod else_if_without_else; -pub mod empty_enum; -pub mod entry; -pub mod enum_clike; -pub mod enum_variants; -pub mod eq_op; -pub mod erasing_op; -pub mod escape; -pub mod eta_reduction; -pub mod eval_order_dependence; -pub mod excessive_bools; -pub mod exit; -pub mod explicit_write; -pub mod fallible_impl_from; -pub mod float_literal; -pub mod floating_point_arithmetic; -pub mod format; -pub mod formatting; -pub mod functions; -pub mod get_last_with_len; -pub mod identity_conversion; -pub mod identity_op; -pub mod if_let_some_result; -pub mod if_not_else; -pub mod implicit_return; -pub mod indexing_slicing; -pub mod infinite_iter; -pub mod inherent_impl; -pub mod inherent_to_string; -pub mod inline_fn_without_body; -pub mod int_plus_one; -pub mod integer_division; -pub mod items_after_statements; -pub mod large_enum_variant; -pub mod large_stack_arrays; -pub mod len_zero; -pub mod let_if_seq; -pub mod let_underscore; -pub mod lifetimes; -pub mod literal_representation; -pub mod loops; -pub mod macro_use; -pub mod main_recursion; -pub mod map_clone; -pub mod map_unit_fn; -pub mod matches; -pub mod mem_discriminant; -pub mod mem_forget; -pub mod mem_replace; -pub mod methods; -pub mod minmax; -pub mod misc; -pub mod misc_early; -pub mod missing_const_for_fn; -pub mod missing_doc; -pub mod missing_inline; -pub mod modulo_arithmetic; -pub mod multiple_crate_versions; -pub mod mut_key; -pub mod mut_mut; -pub mod mut_reference; -pub mod mutable_debug_assertion; -pub mod mutex_atomic; -pub mod needless_bool; -pub mod needless_borrow; -pub mod needless_borrowed_ref; -pub mod needless_continue; -pub mod needless_pass_by_value; -pub mod needless_update; -pub mod neg_cmp_op_on_partial_ord; -pub mod neg_multiply; -pub mod new_without_default; -pub mod no_effect; -pub mod non_copy_const; -pub mod non_expressive_names; -pub mod open_options; -pub mod option_env_unwrap; -pub mod overflow_check_conditional; -pub mod panic_unimplemented; -pub mod partialeq_ne_impl; -pub mod path_buf_push_overwrite; -pub mod precedence; -pub mod ptr; -pub mod ptr_offset_with_cast; -pub mod question_mark; -pub mod ranges; -pub mod redundant_clone; -pub mod redundant_field_names; -pub mod redundant_pattern_matching; -pub mod redundant_pub_crate; -pub mod redundant_static_lifetimes; -pub mod reference; -pub mod regex; -pub mod returns; -pub mod serde_api; -pub mod shadow; -pub mod single_component_path_imports; -pub mod slow_vector_initialization; -pub mod strings; -pub mod suspicious_trait_impl; -pub mod swap; -pub mod tabs_in_doc_comments; -pub mod temporary_assignment; -pub mod to_digit_is_some; -pub mod trait_bounds; -pub mod transmute; -pub mod transmuting_null; -pub mod trivially_copy_pass_by_ref; -pub mod try_err; -pub mod types; -pub mod unicode; -pub mod unnamed_address; -pub mod unsafe_removed_from_name; -pub mod unused_io_amount; -pub mod unused_self; -pub mod unwrap; -pub mod use_self; -pub mod vec; -pub mod verbose_file_reads; -pub mod wildcard_dependencies; -pub mod wildcard_imports; -pub mod write; -pub mod zero_div_zero; +mod approx_const; +mod arithmetic; +mod as_conversions; +mod assertions_on_constants; +mod assign_ops; +mod atomic_ordering; +mod attrs; +mod bit_mask; +mod blacklisted_name; +mod block_in_if_condition; +mod booleans; +mod bytecount; +mod cargo_common_metadata; +mod checked_conversions; +mod cognitive_complexity; +mod collapsible_if; +mod comparison_chain; +mod copies; +mod copy_iterator; +mod dbg_macro; +mod default_trait_access; +mod derive; +mod doc; +mod double_comparison; +mod double_parens; +mod drop_bounds; +mod drop_forget_ref; +mod duration_subsec; +mod else_if_without_else; +mod empty_enum; +mod entry; +mod enum_clike; +mod enum_variants; +mod eq_op; +mod erasing_op; +mod escape; +mod eta_reduction; +mod eval_order_dependence; +mod excessive_bools; +mod exit; +mod explicit_write; +mod fallible_impl_from; +mod float_literal; +mod floating_point_arithmetic; +mod format; +mod formatting; +mod functions; +mod get_last_with_len; +mod identity_conversion; +mod identity_op; +mod if_let_some_result; +mod if_not_else; +mod implicit_return; +mod indexing_slicing; +mod infinite_iter; +mod inherent_impl; +mod inherent_to_string; +mod inline_fn_without_body; +mod int_plus_one; +mod integer_division; +mod items_after_statements; +mod large_enum_variant; +mod large_stack_arrays; +mod len_zero; +mod let_if_seq; +mod let_underscore; +mod lifetimes; +mod literal_representation; +mod loops; +mod macro_use; +mod main_recursion; +mod map_clone; +mod map_unit_fn; +mod matches; +mod mem_discriminant; +mod mem_forget; +mod mem_replace; +mod methods; +mod minmax; +mod misc; +mod misc_early; +mod missing_const_for_fn; +mod missing_doc; +mod missing_inline; +mod modulo_arithmetic; +mod multiple_crate_versions; +mod mut_key; +mod mut_mut; +mod mut_reference; +mod mutable_debug_assertion; +mod mutex_atomic; +mod needless_bool; +mod needless_borrow; +mod needless_borrowed_ref; +mod needless_continue; +mod needless_pass_by_value; +mod needless_update; +mod neg_cmp_op_on_partial_ord; +mod neg_multiply; +mod new_without_default; +mod no_effect; +mod non_copy_const; +mod non_expressive_names; +mod open_options; +mod option_env_unwrap; +mod overflow_check_conditional; +mod panic_unimplemented; +mod partialeq_ne_impl; +mod path_buf_push_overwrite; +mod precedence; +mod ptr; +mod ptr_offset_with_cast; +mod question_mark; +mod ranges; +mod redundant_clone; +mod redundant_field_names; +mod redundant_pattern_matching; +mod redundant_pub_crate; +mod redundant_static_lifetimes; +mod reference; +mod regex; +mod returns; +mod serde_api; +mod shadow; +mod single_component_path_imports; +mod slow_vector_initialization; +mod strings; +mod suspicious_trait_impl; +mod swap; +mod tabs_in_doc_comments; +mod temporary_assignment; +mod to_digit_is_some; +mod trait_bounds; +mod transmute; +mod transmuting_null; +mod trivially_copy_pass_by_ref; +mod try_err; +mod types; +mod unicode; +mod unnamed_address; +mod unsafe_removed_from_name; +mod unused_io_amount; +mod unused_self; +mod unwrap; +mod use_self; +mod vec; +mod verbose_file_reads; +mod wildcard_dependencies; +mod wildcard_imports; +mod write; +mod zero_div_zero; // end lints modules, do not remove this comment, it’s used in `update_lints` pub use crate::utils::conf::Conf; @@ -828,6 +828,12 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &unwrap::PANICKING_UNWRAP, &unwrap::UNNECESSARY_UNWRAP, &use_self::USE_SELF, + &utils::internal_lints::CLIPPY_LINTS_INTERNAL, + &utils::internal_lints::COMPILER_LINT_FUNCTIONS, + &utils::internal_lints::DEFAULT_LINT, + &utils::internal_lints::LINT_WITHOUT_LINT_PASS, + &utils::internal_lints::OUTER_EXPN_EXPN_DATA, + &utils::internal_lints::PRODUCE_ICE, &vec::USELESS_VEC, &verbose_file_reads::VERBOSE_FILE_READS, &wildcard_dependencies::WILDCARD_DEPENDENCIES, diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index 20b793f95ded..4298e62b8037 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -1197,3 +1197,40 @@ where None } + +#[test] +fn test_overlapping() { + use rustc_span::source_map::DUMMY_SP; + + let sp = |s, e| SpannedRange { + span: DUMMY_SP, + node: (s, e), + }; + + assert_eq!(None, overlapping::(&[])); + assert_eq!(None, overlapping(&[sp(1, Bound::Included(4))])); + assert_eq!( + None, + overlapping(&[sp(1, Bound::Included(4)), sp(5, Bound::Included(6))]) + ); + assert_eq!( + None, + overlapping(&[ + sp(1, Bound::Included(4)), + sp(5, Bound::Included(6)), + sp(10, Bound::Included(11)) + ],) + ); + assert_eq!( + Some((&sp(1, Bound::Included(4)), &sp(3, Bound::Included(6)))), + overlapping(&[sp(1, Bound::Included(4)), sp(3, Bound::Included(6))]) + ); + assert_eq!( + Some((&sp(5, Bound::Included(6)), &sp(6, Bound::Included(11)))), + overlapping(&[ + sp(1, Bound::Included(4)), + sp(5, Bound::Included(6)), + sp(6, Bound::Included(11)) + ],) + ); +} diff --git a/tests/matches.rs b/tests/matches.rs deleted file mode 100644 index 6691c074caf9..000000000000 --- a/tests/matches.rs +++ /dev/null @@ -1,42 +0,0 @@ -#![feature(rustc_private)] - -extern crate rustc_span; -use std::collections::Bound; - -#[test] -fn test_overlapping() { - use clippy_lints::matches::overlapping; - use rustc_span::source_map::DUMMY_SP; - - let sp = |s, e| clippy_lints::matches::SpannedRange { - span: DUMMY_SP, - node: (s, e), - }; - - assert_eq!(None, overlapping::(&[])); - assert_eq!(None, overlapping(&[sp(1, Bound::Included(4))])); - assert_eq!( - None, - overlapping(&[sp(1, Bound::Included(4)), sp(5, Bound::Included(6))]) - ); - assert_eq!( - None, - overlapping(&[ - sp(1, Bound::Included(4)), - sp(5, Bound::Included(6)), - sp(10, Bound::Included(11)) - ],) - ); - assert_eq!( - Some((&sp(1, Bound::Included(4)), &sp(3, Bound::Included(6)))), - overlapping(&[sp(1, Bound::Included(4)), sp(3, Bound::Included(6))]) - ); - assert_eq!( - Some((&sp(5, Bound::Included(6)), &sp(6, Bound::Included(11)))), - overlapping(&[ - sp(1, Bound::Included(4)), - sp(5, Bound::Included(6)), - sp(6, Bound::Included(11)) - ],) - ); -}