]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/lib.rs
Lint on `Err(_)` arm of a match
[rust.git] / clippy_lints / src / lib.rs
1 // error-pattern:cargo-clippy
2
3 #![feature(box_syntax)]
4 #![feature(collections)]
5 #![feature(custom_attribute)]
6 #![feature(i128_type)]
7 #![feature(i128)]
8 #![feature(rustc_private)]
9 #![feature(slice_patterns)]
10 #![feature(stmt_expr_attributes)]
11 #![feature(conservative_impl_trait)]
12 #![feature(collections_bound)]
13
14 #![allow(indexing_slicing, shadow_reuse, unknown_lints, missing_docs_in_private_items)]
15 #![allow(needless_lifetimes)]
16
17 extern crate syntax;
18 #[macro_use]
19 extern crate rustc;
20 extern crate rustc_data_structures;
21
22 extern crate toml;
23
24 // Only for the compile time checking of paths
25 extern crate core;
26 extern crate collections;
27
28 // for unicode nfc normalization
29 extern crate unicode_normalization;
30
31 // for semver check in attrs.rs
32 extern crate semver;
33
34 // for regex checking
35 extern crate regex_syntax;
36
37 // for finding minimal boolean expressions
38 extern crate quine_mc_cluskey;
39
40 extern crate rustc_errors;
41 extern crate rustc_plugin;
42 extern crate rustc_const_eval;
43 extern crate rustc_const_math;
44
45 #[macro_use]
46 extern crate matches as matches_macro;
47
48 macro_rules! declare_restriction_lint {
49     { pub $name:tt, $description:tt } => {
50         declare_lint! { pub $name, Allow, $description }
51     };
52 }
53
54 pub mod consts;
55 #[macro_use]
56 pub mod utils;
57
58 // begin lints modules, do not remove this comment, it’s used in `update_lints`
59 pub mod approx_const;
60 pub mod arithmetic;
61 pub mod array_indexing;
62 pub mod assign_ops;
63 pub mod attrs;
64 pub mod bit_mask;
65 pub mod blacklisted_name;
66 pub mod block_in_if_condition;
67 pub mod booleans;
68 pub mod collapsible_if;
69 pub mod copies;
70 pub mod cyclomatic_complexity;
71 pub mod derive;
72 pub mod doc;
73 pub mod double_parens;
74 pub mod drop_forget_ref;
75 pub mod empty_enum;
76 pub mod entry;
77 pub mod enum_clike;
78 pub mod enum_glob_use;
79 pub mod enum_variants;
80 pub mod eq_op;
81 pub mod escape;
82 pub mod eta_reduction;
83 pub mod eval_order_dependence;
84 pub mod format;
85 pub mod formatting;
86 pub mod functions;
87 pub mod identity_op;
88 pub mod if_let_redundant_pattern_matching;
89 pub mod if_not_else;
90 pub mod items_after_statements;
91 pub mod large_enum_variant;
92 pub mod len_zero;
93 pub mod let_if_seq;
94 pub mod lifetimes;
95 pub mod loops;
96 pub mod map_clone;
97 pub mod matches;
98 pub mod mem_forget;
99 pub mod methods;
100 pub mod minmax;
101 pub mod misc;
102 pub mod misc_early;
103 pub mod missing_doc;
104 pub mod mut_mut;
105 pub mod mut_reference;
106 pub mod mutex_atomic;
107 pub mod needless_bool;
108 pub mod needless_borrow;
109 pub mod needless_update;
110 pub mod neg_multiply;
111 pub mod new_without_default;
112 pub mod no_effect;
113 pub mod non_expressive_names;
114 pub mod ok_if_let;
115 pub mod open_options;
116 pub mod overflow_check_conditional;
117 pub mod panic;
118 pub mod partialeq_ne_impl;
119 pub mod precedence;
120 pub mod print;
121 pub mod ptr;
122 pub mod ranges;
123 pub mod reference;
124 pub mod regex;
125 pub mod returns;
126 pub mod serde;
127 pub mod shadow;
128 pub mod strings;
129 pub mod swap;
130 pub mod temporary_assignment;
131 pub mod transmute;
132 pub mod types;
133 pub mod unicode;
134 pub mod unsafe_removed_from_name;
135 pub mod unused_io_amount;
136 pub mod unused_label;
137 pub mod vec;
138 pub mod zero_div_zero;
139 // end lints modules, do not remove this comment, it’s used in `update_lints`
140
141 mod reexport {
142     pub use syntax::ast::{Name, NodeId};
143 }
144
145 #[cfg_attr(rustfmt, rustfmt_skip)]
146 pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
147     let conf = match utils::conf::file_from_args(reg.args()) {
148         Ok(file_name) => {
149             // if the user specified a file, it must exist, otherwise default to `clippy.toml` but
150             // do not require the file to exist
151             let file_name = if let Some(file_name) = file_name {
152                 Some(file_name)
153             } else {
154                 match utils::conf::lookup_conf_file() {
155                     Ok(path) => path,
156                     Err(error) => {
157                         reg.sess.struct_err(&format!("error reading Clippy's configuration file: {}", error)).emit();
158                         None
159                     }
160                 }
161             };
162
163             let (conf, errors) = utils::conf::read(file_name.as_ref().map(|p| p.as_ref()));
164
165             // all conf errors are non-fatal, we just use the default conf in case of error
166             for error in errors {
167                 reg.sess.struct_err(&format!("error reading Clippy's configuration file: {}", error)).emit();
168             }
169
170             conf
171         }
172         Err((err, span)) => {
173             reg.sess.struct_span_err(span, err)
174                     .span_note(span, "Clippy will use default configuration")
175                     .emit();
176             utils::conf::Conf::default()
177         }
178     };
179
180     let mut store = reg.sess.lint_store.borrow_mut();
181     store.register_removed(
182         "extend_from_slice",
183         "`.extend_from_slice(_)` is a faster way to extend a Vec by a slice",
184     );
185     store.register_removed(
186         "unstable_as_slice",
187         "`Vec::as_slice` has been stabilized in 1.7",
188     );
189     store.register_removed(
190         "unstable_as_mut_slice",
191         "`Vec::as_mut_slice` has been stabilized in 1.7",
192     );
193     store.register_removed(
194         "str_to_string",
195         "using `str::to_string` is common even today and specialization will likely happen soon",
196     );
197     store.register_removed(
198         "string_to_string",
199         "using `string::to_string` is common even today and specialization will likely happen soon",
200     );
201     // end deprecated lints, do not remove this comment, it’s used in `update_lints`
202
203     reg.register_late_lint_pass(box serde::Serde);
204     reg.register_early_lint_pass(box utils::internal_lints::Clippy);
205     reg.register_late_lint_pass(box utils::internal_lints::LintWithoutLintPass::default());
206     reg.register_late_lint_pass(box utils::inspector::Pass);
207     reg.register_late_lint_pass(box types::TypePass);
208     reg.register_late_lint_pass(box booleans::NonminimalBool);
209     reg.register_late_lint_pass(box eq_op::EqOp);
210     reg.register_early_lint_pass(box enum_variants::EnumVariantNames::new(conf.enum_variant_name_threshold));
211     reg.register_late_lint_pass(box enum_glob_use::EnumGlobUse);
212     reg.register_late_lint_pass(box enum_clike::UnportableVariant);
213     reg.register_late_lint_pass(box bit_mask::BitMask);
214     reg.register_late_lint_pass(box ptr::PointerPass);
215     reg.register_late_lint_pass(box needless_bool::NeedlessBool);
216     reg.register_late_lint_pass(box needless_bool::BoolComparison);
217     reg.register_late_lint_pass(box approx_const::Pass);
218     reg.register_late_lint_pass(box misc::Pass);
219     reg.register_early_lint_pass(box precedence::Precedence);
220     reg.register_late_lint_pass(box eta_reduction::EtaPass);
221     reg.register_late_lint_pass(box identity_op::IdentityOp);
222     reg.register_early_lint_pass(box items_after_statements::ItemsAfterStatements);
223     reg.register_late_lint_pass(box mut_mut::MutMut);
224     reg.register_late_lint_pass(box mut_reference::UnnecessaryMutPassed);
225     reg.register_late_lint_pass(box len_zero::LenZero);
226     reg.register_late_lint_pass(box attrs::AttrPass);
227     reg.register_early_lint_pass(box collapsible_if::CollapsibleIf);
228     reg.register_late_lint_pass(box block_in_if_condition::BlockInIfCondition);
229     reg.register_late_lint_pass(box unicode::Unicode);
230     reg.register_late_lint_pass(box strings::StringAdd);
231     reg.register_early_lint_pass(box returns::ReturnPass);
232     reg.register_late_lint_pass(box methods::Pass);
233     reg.register_late_lint_pass(box shadow::Pass);
234     reg.register_late_lint_pass(box types::LetPass);
235     reg.register_late_lint_pass(box types::UnitCmp);
236     reg.register_late_lint_pass(box loops::Pass);
237     reg.register_late_lint_pass(box lifetimes::LifetimePass);
238     reg.register_late_lint_pass(box entry::HashMapLint);
239     reg.register_late_lint_pass(box ranges::StepByZero);
240     reg.register_late_lint_pass(box types::CastPass);
241     reg.register_late_lint_pass(box types::TypeComplexityPass::new(conf.type_complexity_threshold));
242     reg.register_late_lint_pass(box matches::MatchPass);
243     reg.register_late_lint_pass(box minmax::MinMaxPass);
244     reg.register_late_lint_pass(box open_options::NonSensical);
245     reg.register_late_lint_pass(box zero_div_zero::Pass);
246     reg.register_late_lint_pass(box mutex_atomic::MutexAtomic);
247     reg.register_late_lint_pass(box needless_update::Pass);
248     reg.register_late_lint_pass(box needless_borrow::NeedlessBorrow);
249     reg.register_late_lint_pass(box no_effect::Pass);
250     reg.register_late_lint_pass(box map_clone::Pass);
251     reg.register_late_lint_pass(box temporary_assignment::Pass);
252     reg.register_late_lint_pass(box transmute::Transmute);
253     reg.register_late_lint_pass(
254         box cyclomatic_complexity::CyclomaticComplexity::new(conf.cyclomatic_complexity_threshold)
255     );
256     reg.register_late_lint_pass(box escape::Pass{too_large_for_stack: conf.too_large_for_stack});
257     reg.register_early_lint_pass(box misc_early::MiscEarly);
258     reg.register_late_lint_pass(box array_indexing::ArrayIndexing);
259     reg.register_late_lint_pass(box panic::Pass);
260     reg.register_late_lint_pass(box strings::StringLitAsBytes);
261     reg.register_late_lint_pass(box derive::Derive);
262     reg.register_late_lint_pass(box types::CharLitAsU8);
263     reg.register_late_lint_pass(box print::Pass);
264     reg.register_late_lint_pass(box vec::Pass);
265     reg.register_early_lint_pass(box non_expressive_names::NonExpressiveNames {
266         max_single_char_names: conf.max_single_char_names,
267     });
268     reg.register_late_lint_pass(box drop_forget_ref::Pass);
269     reg.register_late_lint_pass(box empty_enum::EmptyEnum);
270     reg.register_late_lint_pass(box types::AbsurdExtremeComparisons);
271     reg.register_late_lint_pass(box types::InvalidUpcastComparisons);
272     reg.register_late_lint_pass(box regex::Pass::default());
273     reg.register_late_lint_pass(box copies::CopyAndPaste);
274     reg.register_late_lint_pass(box format::Pass);
275     reg.register_early_lint_pass(box formatting::Formatting);
276     reg.register_late_lint_pass(box swap::Swap);
277     reg.register_early_lint_pass(box if_not_else::IfNotElse);
278     reg.register_late_lint_pass(box overflow_check_conditional::OverflowCheckConditional);
279     reg.register_late_lint_pass(box unused_label::UnusedLabel);
280     reg.register_late_lint_pass(box new_without_default::NewWithoutDefault);
281     reg.register_late_lint_pass(box blacklisted_name::BlackListedName::new(conf.blacklisted_names));
282     reg.register_late_lint_pass(box functions::Functions::new(conf.too_many_arguments_threshold));
283     reg.register_early_lint_pass(box doc::Doc::new(conf.doc_valid_idents));
284     reg.register_late_lint_pass(box neg_multiply::NegMultiply);
285     reg.register_early_lint_pass(box unsafe_removed_from_name::UnsafeNameRemoval);
286     reg.register_late_lint_pass(box mem_forget::MemForget);
287     reg.register_late_lint_pass(box arithmetic::Arithmetic::default());
288     reg.register_late_lint_pass(box assign_ops::AssignOps);
289     reg.register_late_lint_pass(box let_if_seq::LetIfSeq);
290     reg.register_late_lint_pass(box eval_order_dependence::EvalOrderDependence);
291     reg.register_late_lint_pass(box missing_doc::MissingDoc::new());
292     reg.register_late_lint_pass(box ok_if_let::Pass);
293     reg.register_late_lint_pass(box if_let_redundant_pattern_matching::Pass);
294     reg.register_late_lint_pass(box partialeq_ne_impl::Pass);
295     reg.register_early_lint_pass(box reference::Pass);
296     reg.register_early_lint_pass(box double_parens::DoubleParens);
297     reg.register_late_lint_pass(box unused_io_amount::UnusedIoAmount);
298     reg.register_late_lint_pass(box large_enum_variant::LargeEnumVariant::new(conf.enum_variant_size_threshold));
299
300     reg.register_lint_group("clippy_restrictions", vec![
301         arithmetic::FLOAT_ARITHMETIC,
302         arithmetic::INTEGER_ARITHMETIC,
303         array_indexing::INDEXING_SLICING,
304         assign_ops::ASSIGN_OPS,
305     ]);
306
307     reg.register_lint_group("clippy_pedantic", vec![
308         booleans::NONMINIMAL_BOOL,
309         empty_enum::EMPTY_ENUM,
310         enum_glob_use::ENUM_GLOB_USE,
311         enum_variants::PUB_ENUM_VARIANT_NAMES,
312         enum_variants::STUTTER,
313         if_not_else::IF_NOT_ELSE,
314         items_after_statements::ITEMS_AFTER_STATEMENTS,
315         matches::SINGLE_MATCH_ELSE,
316         mem_forget::MEM_FORGET,
317         methods::FILTER_MAP,
318         methods::OPTION_MAP_UNWRAP_OR,
319         methods::OPTION_MAP_UNWRAP_OR_ELSE,
320         methods::OPTION_UNWRAP_USED,
321         methods::RESULT_UNWRAP_USED,
322         methods::WRONG_PUB_SELF_CONVENTION,
323         misc::USED_UNDERSCORE_BINDING,
324         misc_early::UNSEPARATED_LITERAL_SUFFIX,
325         missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS,
326         mut_mut::MUT_MUT,
327         mutex_atomic::MUTEX_INTEGER,
328         non_expressive_names::SIMILAR_NAMES,
329         print::PRINT_STDOUT,
330         print::USE_DEBUG,
331         shadow::SHADOW_REUSE,
332         shadow::SHADOW_SAME,
333         shadow::SHADOW_UNRELATED,
334         strings::STRING_ADD,
335         strings::STRING_ADD_ASSIGN,
336         types::CAST_POSSIBLE_TRUNCATION,
337         types::CAST_POSSIBLE_WRAP,
338         types::CAST_PRECISION_LOSS,
339         types::CAST_SIGN_LOSS,
340         types::INVALID_UPCAST_COMPARISONS,
341         unicode::NON_ASCII_LITERAL,
342         unicode::UNICODE_NOT_NFC,
343     ]);
344
345     reg.register_lint_group("clippy_internal", vec![
346         utils::internal_lints::CLIPPY_LINTS_INTERNAL,
347         utils::internal_lints::LINT_WITHOUT_LINT_PASS,
348     ]);
349
350     reg.register_lint_group("clippy", vec![
351         approx_const::APPROX_CONSTANT,
352         array_indexing::OUT_OF_BOUNDS_INDEXING,
353         assign_ops::ASSIGN_OP_PATTERN,
354         assign_ops::MISREFACTORED_ASSIGN_OP,
355         attrs::DEPRECATED_SEMVER,
356         attrs::INLINE_ALWAYS,
357         attrs::USELESS_ATTRIBUTE,
358         bit_mask::BAD_BIT_MASK,
359         bit_mask::INEFFECTIVE_BIT_MASK,
360         blacklisted_name::BLACKLISTED_NAME,
361         block_in_if_condition::BLOCK_IN_IF_CONDITION_EXPR,
362         block_in_if_condition::BLOCK_IN_IF_CONDITION_STMT,
363         booleans::LOGIC_BUG,
364         collapsible_if::COLLAPSIBLE_IF,
365         copies::IF_SAME_THEN_ELSE,
366         copies::IFS_SAME_COND,
367         copies::MATCH_SAME_ARMS,
368         cyclomatic_complexity::CYCLOMATIC_COMPLEXITY,
369         derive::DERIVE_HASH_XOR_EQ,
370         derive::EXPL_IMPL_CLONE_ON_COPY,
371         doc::DOC_MARKDOWN,
372         double_parens::DOUBLE_PARENS,
373         drop_forget_ref::DROP_REF,
374         drop_forget_ref::FORGET_REF,
375         entry::MAP_ENTRY,
376         enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT,
377         enum_variants::ENUM_VARIANT_NAMES,
378         enum_variants::MODULE_INCEPTION,
379         eq_op::EQ_OP,
380         escape::BOXED_LOCAL,
381         eta_reduction::REDUNDANT_CLOSURE,
382         eval_order_dependence::DIVERGING_SUB_EXPRESSION,
383         eval_order_dependence::EVAL_ORDER_DEPENDENCE,
384         format::USELESS_FORMAT,
385         formatting::POSSIBLE_MISSING_COMMA,
386         formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING,
387         formatting::SUSPICIOUS_ELSE_FORMATTING,
388         functions::NOT_UNSAFE_PTR_ARG_DEREF,
389         functions::TOO_MANY_ARGUMENTS,
390         identity_op::IDENTITY_OP,
391         if_let_redundant_pattern_matching::IF_LET_REDUNDANT_PATTERN_MATCHING,
392         large_enum_variant::LARGE_ENUM_VARIANT,
393         len_zero::LEN_WITHOUT_IS_EMPTY,
394         len_zero::LEN_ZERO,
395         let_if_seq::USELESS_LET_IF_SEQ,
396         lifetimes::NEEDLESS_LIFETIMES,
397         lifetimes::UNUSED_LIFETIMES,
398         loops::EMPTY_LOOP,
399         loops::EXPLICIT_COUNTER_LOOP,
400         loops::EXPLICIT_INTO_ITER_LOOP,
401         loops::EXPLICIT_ITER_LOOP,
402         loops::FOR_KV_MAP,
403         loops::FOR_LOOP_OVER_OPTION,
404         loops::FOR_LOOP_OVER_RESULT,
405         loops::ITER_NEXT_LOOP,
406         loops::NEEDLESS_RANGE_LOOP,
407         loops::REVERSE_RANGE_LOOP,
408         loops::UNUSED_COLLECT,
409         loops::WHILE_LET_LOOP,
410         loops::WHILE_LET_ON_ITERATOR,
411         map_clone::MAP_CLONE,
412         matches::MATCH_BOOL,
413         matches::MATCH_OVERLAPPING_ARM,
414         matches::MATCH_REF_PATS,
415         matches::MATCH_WILD_ERR_ARM,
416         matches::SINGLE_MATCH,
417         methods::CHARS_NEXT_CMP,
418         methods::CLONE_DOUBLE_REF,
419         methods::CLONE_ON_COPY,
420         methods::FILTER_NEXT,
421         methods::GET_UNWRAP,
422         methods::ITER_NTH,
423         methods::ITER_SKIP_NEXT,
424         methods::NEW_RET_NO_SELF,
425         methods::OK_EXPECT,
426         methods::OR_FUN_CALL,
427         methods::SEARCH_IS_SOME,
428         methods::SHOULD_IMPLEMENT_TRAIT,
429         methods::SINGLE_CHAR_PATTERN,
430         methods::STRING_EXTEND_CHARS,
431         methods::TEMPORARY_CSTRING_AS_PTR,
432         methods::WRONG_SELF_CONVENTION,
433         minmax::MIN_MAX,
434         misc::CMP_NAN,
435         misc::CMP_OWNED,
436         misc::FLOAT_CMP,
437         misc::MODULO_ONE,
438         misc::REDUNDANT_PATTERN,
439         misc::SHORT_CIRCUIT_STATEMENT,
440         misc::TOPLEVEL_REF_ARG,
441         misc_early::BUILTIN_TYPE_SHADOW,
442         misc_early::DOUBLE_NEG,
443         misc_early::DUPLICATE_UNDERSCORE_ARGUMENT,
444         misc_early::MIXED_CASE_HEX_LITERALS,
445         misc_early::REDUNDANT_CLOSURE_CALL,
446         misc_early::UNNEEDED_FIELD_PATTERN,
447         misc_early::ZERO_PREFIXED_LITERAL,
448         mut_reference::UNNECESSARY_MUT_PASSED,
449         mutex_atomic::MUTEX_ATOMIC,
450         needless_bool::BOOL_COMPARISON,
451         needless_bool::NEEDLESS_BOOL,
452         needless_borrow::NEEDLESS_BORROW,
453         needless_update::NEEDLESS_UPDATE,
454         neg_multiply::NEG_MULTIPLY,
455         new_without_default::NEW_WITHOUT_DEFAULT,
456         new_without_default::NEW_WITHOUT_DEFAULT_DERIVE,
457         no_effect::NO_EFFECT,
458         no_effect::UNNECESSARY_OPERATION,
459         non_expressive_names::MANY_SINGLE_CHAR_NAMES,
460         ok_if_let::IF_LET_SOME_RESULT,
461         open_options::NONSENSICAL_OPEN_OPTIONS,
462         overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL,
463         panic::PANIC_PARAMS,
464         partialeq_ne_impl::PARTIALEQ_NE_IMPL,
465         precedence::PRECEDENCE,
466         print::PRINT_WITH_NEWLINE,
467         ptr::CMP_NULL,
468         ptr::PTR_ARG,
469         ranges::RANGE_STEP_BY_ZERO,
470         ranges::RANGE_ZIP_WITH_LEN,
471         reference::DEREF_ADDROF,
472         regex::INVALID_REGEX,
473         regex::REGEX_MACRO,
474         regex::TRIVIAL_REGEX,
475         returns::LET_AND_RETURN,
476         returns::NEEDLESS_RETURN,
477         serde::SERDE_API_MISUSE,
478         strings::STRING_LIT_AS_BYTES,
479         swap::ALMOST_SWAPPED,
480         swap::MANUAL_SWAP,
481         temporary_assignment::TEMPORARY_ASSIGNMENT,
482         transmute::CROSSPOINTER_TRANSMUTE,
483         transmute::TRANSMUTE_PTR_TO_REF,
484         transmute::USELESS_TRANSMUTE,
485         transmute::WRONG_TRANSMUTE,
486         types::ABSURD_EXTREME_COMPARISONS,
487         types::BOX_VEC,
488         types::CHAR_LIT_AS_U8,
489         types::LET_UNIT_VALUE,
490         types::LINKEDLIST,
491         types::TYPE_COMPLEXITY,
492         types::UNIT_CMP,
493         unicode::ZERO_WIDTH_SPACE,
494         unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME,
495         unused_io_amount::UNUSED_IO_AMOUNT,
496         unused_label::UNUSED_LABEL,
497         vec::USELESS_VEC,
498         zero_div_zero::ZERO_DIVIDED_BY_ZERO,
499     ]);
500 }
501
502 // only exists to let the dogfood integration test works.
503 // Don't run clippy as an executable directly
504 #[allow(dead_code, print_stdout)]
505 fn main() {
506     panic!("Please use the cargo-clippy executable");
507 }