-use crate::utils::{attr_by_name, in_macro, match_path_ast, span_lint_and_help};
+use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::in_macro;
+use rustc_ast::ast::{AssocItemKind, Extern, FnKind, FnSig, ImplKind, Item, ItemKind, TraitKind, Ty, TyKind};
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
-use rustc_span::Span;
-use syntax::ast::{AssocItemKind, Extern, FnSig, Item, ItemKind, Ty, TyKind};
+use rustc_span::{sym, Span};
use std::convert::TryInto;
declare_clippy_lint! {
- /// **What it does:** Checks for excessive
+ /// ### What it does
+ /// Checks for excessive
/// use of bools in structs.
///
- /// **Why is this bad?** Excessive bools in a struct
+ /// ### Why is this bad?
+ /// Excessive bools in a struct
/// is often a sign that it's used as a state machine,
/// which is much better implemented as an enum.
/// If it's not the case, excessive bools usually benefit
/// from refactoring into two-variant enums for better
/// readability and API.
///
- /// **Known problems:** None.
- ///
- /// **Example:**
+ /// ### Example
/// Bad:
/// ```rust
/// struct S {
}
declare_clippy_lint! {
- /// **What it does:** Checks for excessive use of
+ /// ### What it does
+ /// Checks for excessive use of
/// bools in function definitions.
///
- /// **Why is this bad?** Calls to such functions
+ /// ### Why is this bad?
+ /// Calls to such functions
/// are confusing and error prone, because it's
/// hard to remember argument order and you have
/// no type system support to back you up. Using
/// two-variant enums instead of bools often makes
/// API easier to use.
///
- /// **Known problems:** None.
- ///
- /// **Example:**
+ /// ### Example
/// Bad:
/// ```rust,ignore
/// fn f(is_round: bool, is_hot: bool) { ... }
FN_PARAMS_EXCESSIVE_BOOLS,
span,
&format!("more than {} bools in function parameters", self.max_fn_params_bools),
+ None,
"consider refactoring bools into two-variant enums",
);
}
fn is_bool_ty(ty: &Ty) -> bool {
if let TyKind::Path(None, path) = &ty.kind {
- return match_path_ast(path, &["bool"]);
+ if let [name] = path.segments.as_slice() {
+ return name.ident.name == sym::bool;
+ }
}
false
}
}
match &item.kind {
ItemKind::Struct(variant_data, _) => {
- if attr_by_name(&item.attrs, "repr").is_some() {
+ if item.attrs.iter().any(|attr| attr.has_name(sym::repr)) {
return;
}
STRUCT_EXCESSIVE_BOOLS,
item.span,
&format!("more than {} bools in a struct", self.max_struct_bools),
+ None,
"consider using a state machine or refactoring bools into two-variant enums",
);
}
},
- ItemKind::Impl {
+ ItemKind::Impl(box ImplKind {
of_trait: None, items, ..
- }
- | ItemKind::Trait(_, _, _, _, items) => {
+ })
+ | ItemKind::Trait(box TraitKind(.., items)) => {
for item in items {
- if let AssocItemKind::Fn(fn_sig, _) = &item.kind {
+ if let AssocItemKind::Fn(box FnKind(_, fn_sig, _, _)) = &item.kind {
self.check_fn_sig(cx, fn_sig, item.span);
}
}
},
- ItemKind::Fn(fn_sig, _, _) => self.check_fn_sig(cx, fn_sig, item.span),
+ ItemKind::Fn(box FnKind(_, fn_sig, _, _)) => self.check_fn_sig(cx, fn_sig, item.span),
_ => (),
}
}