use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
-use clippy_utils::{eq_expr_value, get_trait_def_id, in_macro, paths};
+use clippy_utils::{eq_expr_value, get_trait_def_id, paths};
use if_chain::if_chain;
use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
type Map = Map<'tcx>;
fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
- if in_macro(e.span) {
- return;
- }
- match &e.kind {
- ExprKind::Binary(binop, _, _) if binop.node == BinOpKind::Or || binop.node == BinOpKind::And => {
- self.bool_expr(e);
- },
- ExprKind::Unary(UnOp::Not, inner) => {
- if self.cx.typeck_results().node_types()[inner.hir_id].is_bool() {
+ if !e.span.from_expansion() {
+ match &e.kind {
+ ExprKind::Binary(binop, _, _) if binop.node == BinOpKind::Or || binop.node == BinOpKind::And => {
self.bool_expr(e);
- } else {
- walk_expr(self, e);
- }
- },
- _ => walk_expr(self, e),
+ },
+ ExprKind::Unary(UnOp::Not, inner) => {
+ if self.cx.typeck_results().node_types()[inner.hir_id].is_bool() {
+ self.bool_expr(e);
+ }
+ },
+ _ => {},
+ }
}
+ walk_expr(self, e);
}
fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
NestedVisitorMap::None
use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_then};
use clippy_utils::source::{first_line_of_span, indent_of, reindent_multiline, snippet, snippet_opt};
use clippy_utils::{
- both, count_eq, eq_expr_value, get_enclosing_block, get_parent_expr, if_sequence, in_macro, is_else_clause,
- is_lint_allowed, search_same, ContainsName, SpanlessEq, SpanlessHash,
+ both, count_eq, eq_expr_value, get_enclosing_block, get_parent_expr, if_sequence, is_else_clause, is_lint_allowed,
+ search_same, ContainsName, SpanlessEq, SpanlessHash,
};
use if_chain::if_chain;
use rustc_data_structures::fx::FxHashSet;
let eq: &dyn Fn(&&Expr<'_>, &&Expr<'_>) -> bool = &|&lhs, &rhs| -> bool {
// Do not lint if any expr originates from a macro
- if in_macro(lhs.span) || in_macro(rhs.span) {
+ if lhs.span.from_expansion() || rhs.span.from_expansion() {
return false;
}
// Do not spawn warning if `IFS_SAME_COND` already produced it.
use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg};
use clippy_utils::source::snippet_with_macro_callsite;
use clippy_utils::ty::{has_drop, is_copy};
-use clippy_utils::{any_parent_is_automatically_derived, contains_name, in_macro, match_def_path, paths};
+use clippy_utils::{any_parent_is_automatically_derived, contains_name, match_def_path, paths};
use if_chain::if_chain;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
impl LateLintPass<'_> for Default {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if_chain! {
- if !in_macro(expr.span);
+ if !expr.span.from_expansion();
// Avoid cases already linted by `field_reassign_with_default`
if !self.reassigned_linted.contains(&expr.span);
if let ExprKind::Call(path, ..) = expr.kind;
if let StmtKind::Local(local) = stmt.kind;
if let Some(expr) = local.init;
if !any_parent_is_automatically_derived(cx.tcx, expr.hir_id);
- if !in_macro(expr.span);
+ if !expr.span.from_expansion();
// only take bindings to identifiers
if let PatKind::Binding(_, binding_id, ident, _) = local.pat.kind;
// only when assigning `... = Default::default()`
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_context;
use clippy_utils::ty::peel_mid_ty_refs;
-use clippy_utils::{get_parent_node, in_macro, is_lint_allowed};
+use clippy_utils::{get_parent_node, is_lint_allowed};
use rustc_ast::util::parser::PREC_PREFIX;
use rustc_errors::Applicability;
use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, MatchSource, Mutability, Node, UnOp};
}
// Stop processing sub expressions when a macro call is seen
- if in_macro(expr.span) {
+ if expr.span.from_expansion() {
if let Some((state, data)) = self.state.take() {
report(cx, expr, state, data);
}
use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::{in_macro, is_automatically_derived, is_default_equivalent, remove_blocks};
+use clippy_utils::{is_automatically_derived, is_default_equivalent, remove_blocks};
use rustc_hir::{
def::{DefKind, Res},
Body, Expr, ExprKind, GenericArg, Impl, ImplItemKind, Item, ItemKind, Node, PathSegment, QPath, TyKind,
}) = item.kind;
if let attrs = cx.tcx.hir().attrs(item.hir_id());
if !is_automatically_derived(attrs);
- if !in_macro(item.span);
+ if !item.span.from_expansion();
if let Some(def_id) = trait_ref.trait_def_id();
if cx.tcx.is_diagnostic_item(sym::Default, def_id);
if let impl_item_hir = child.id.hir_id();
use clippy_utils::diagnostics::{multispan_sugg, span_lint, span_lint_and_then};
use clippy_utils::source::snippet;
use clippy_utils::ty::{implements_trait, is_copy};
-use clippy_utils::{
- ast_utils::is_useless_with_eq_exprs, eq_expr_value, higher, in_macro, is_expn_of, is_in_test_function,
-};
+use clippy_utils::{ast_utils::is_useless_with_eq_exprs, eq_expr_value, higher, is_expn_of, is_in_test_function};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, StmtKind};
}
let macro_with_not_op = |expr_kind: &ExprKind<'_>| {
if let ExprKind::Unary(_, expr) = *expr_kind {
- in_macro(expr.span)
+ expr.span.from_expansion()
} else {
false
}
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};
impl EarlyLintPass for ExcessiveBools {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
- if in_macro(item.span) {
+ if item.span.from_expansion() {
return;
}
match &item.kind {
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::higher;
-use clippy_utils::{in_macro, SpanlessEq};
+use clippy_utils::SpanlessEq;
use if_chain::if_chain;
use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
- if in_macro(expr.span) {
+ if expr.span.from_expansion() {
return;
}
if_chain! {
use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::in_macro;
use clippy_utils::source::snippet;
use if_chain::if_chain;
use rustc_data_structures::fx::FxHashMap;
impl LateLintPass<'_> for InconsistentStructConstructor {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
if_chain! {
- if !in_macro(expr.span);
+ if !expr.span.from_expansion();
if let ExprKind::Struct(qpath, fields, base) = expr.kind;
let ty = cx.typeck_results().expr_ty(expr);
if let Some(adt_def) = ty.ty_adt_def();
//! lint on inherent implementations
use clippy_utils::diagnostics::span_lint_and_note;
-use clippy_utils::{in_macro, is_lint_allowed};
+use clippy_utils::is_lint_allowed;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::{def_id::LocalDefId, Item, ItemKind, Node};
use rustc_lint::{LateContext, LateLintPass};
..
}) = cx.tcx.hir().get(id)
{
- (!in_macro(span) && impl_item.generics.params.is_empty() && !is_lint_allowed(cx, MULTIPLE_INHERENT_IMPL, id))
- .then(|| span)
+ (!span.from_expansion()
+ && impl_item.generics.params.is_empty()
+ && !is_lint_allowed(cx, MULTIPLE_INHERENT_IMPL, id))
+ .then(|| span)
} else {
None
}
use clippy_utils::diagnostics::span_lint;
-use clippy_utils::{in_macro, trait_ref_of_method};
+use clippy_utils::trait_ref_of_method;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir::intravisit::{
walk_fn_decl, walk_generic_param, walk_generics, walk_item, walk_param_bound, walk_poly_trait_ref, walk_ty,
span: Span,
report_extra_lifetimes: bool,
) {
- if in_macro(span) || has_where_lifetimes(cx, &generics.where_clause) {
+ if span.from_expansion() || has_where_lifetimes(cx, &generics.where_clause) {
return;
}
//! floating-point literal expressions.
use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::numeric_literal::{NumericLiteral, Radix};
use clippy_utils::source::snippet_opt;
-use clippy_utils::{
- in_macro,
- numeric_literal::{NumericLiteral, Radix},
-};
use if_chain::if_chain;
use rustc_ast::ast::{Expr, ExprKind, Lit, LitKind};
use rustc_errors::Applicability;
| WarningType::InconsistentDigitGrouping
| WarningType::UnusualByteGroupings
| WarningType::LargeDigitGroups => {
- !in_macro(lit.span)
+ !lit.span.from_expansion()
}
WarningType::DecimalRepresentation | WarningType::MistypedLiteralSuffix => {
true
use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::in_macro;
use clippy_utils::source::snippet;
use hir::def::{DefKind, Res};
use if_chain::if_chain;
use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::hygiene::ExpnKind;
use rustc_span::{edition::Edition, sym, Span};
declare_clippy_lint! {
}
}
}
+
+fn in_macro(span: Span) -> bool {
+ span.from_expansion() && !matches!(span.ctxt().outer_expn_data().kind, ExpnKind::Desugaring(..))
+}
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item, match_type, peel_mid_ty_refs};
use clippy_utils::visitors::is_local_used;
use clippy_utils::{
- get_parent_expr, in_macro, is_expn_of, is_lang_ctor, is_lint_allowed, is_refutable, is_unit_expr, is_wild,
- meets_msrv, msrvs, path_to_local, path_to_local_id, peel_hir_pat_refs, peel_n_hir_expr_refs, recurse_or_patterns,
- remove_blocks, strip_pat_refs,
+ get_parent_expr, is_expn_of, is_lang_ctor, is_lint_allowed, is_refutable, is_unit_expr, is_wild, meets_msrv, msrvs,
+ path_to_local, path_to_local_id, peel_hir_pat_refs, peel_n_hir_expr_refs, recurse_or_patterns, remove_blocks,
+ strip_pat_refs,
};
use clippy_utils::{paths, search_same, SpanlessEq, SpanlessHash};
use core::array;
};
use rustc_hir::{HirIdMap, HirIdSet};
use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, Ty, TyS, VariantDef};
use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
impl<'tcx> LateLintPass<'tcx> for Matches {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
- if in_external_macro(cx.sess(), expr.span) || in_macro(expr.span) {
+ if expr.span.from_expansion() {
return;
}
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'_>) {
if_chain! {
- if !in_external_macro(cx.sess(), local.span);
- if !in_macro(local.span);
+ if !local.span.from_expansion();
if let Some(expr) = local.init;
if let ExprKind::Match(target, arms, MatchSource::Normal) = expr.kind;
if arms.len() == 1 && arms[0].guard.is_none();
fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
if_chain! {
- if !in_external_macro(cx.sess(), pat.span);
- if !in_macro(pat.span);
+ if !pat.span.from_expansion();
if let PatKind::Struct(QPath::Resolved(_, path), fields, true) = pat.kind;
if let Some(def_id) = path.res.opt_def_id();
let ty = cx.tcx.type_of(def_id);
#[rustfmt::skip]
fn check_single_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) {
if arms.len() == 2 && arms[0].guard.is_none() && arms[1].guard.is_none() {
- if in_macro(expr.span) {
+ if expr.span.from_expansion() {
// Don't lint match expressions present in
// macro_rules! block
return;
#[allow(clippy::too_many_lines)]
fn check_match_single_binding<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], expr: &Expr<'_>) {
- if in_macro(expr.span) || arms.len() != 1 || is_refutable(cx, arms[0].pat) {
+ if expr.span.from_expansion() || arms.len() != 1 || is_refutable(cx, arms[0].pat) {
return;
}
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
use clippy_utils::source::{snippet, snippet_with_applicability};
use clippy_utils::ty::is_non_aggregate_primitive_type;
-use clippy_utils::{in_macro, is_default_equivalent, is_lang_ctor, match_def_path, meets_msrv, msrvs, paths};
+use clippy_utils::{is_default_equivalent, is_lang_ctor, match_def_path, meets_msrv, msrvs, paths};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::LangItem::OptionNone;
expr_span,
"replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`",
|diag| {
- if !in_macro(expr_span) {
+ if !expr_span.from_expansion() {
let suggestion = format!("std::mem::take({})", snippet(cx, dest.span, ""));
diag.span_suggestion(
use super::{contains_return, BIND_INSTEAD_OF_MAP};
use clippy_utils::diagnostics::{multispan_sugg_with_applicability, span_lint_and_sugg, span_lint_and_then};
use clippy_utils::source::{snippet, snippet_with_macro_callsite};
-use clippy_utils::{in_macro, remove_blocks, visitors::find_all_ret_expressions};
+use clippy_utils::{remove_blocks, visitors::find_all_ret_expressions};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir as hir;
let mut suggs = Vec::new();
let can_sugg: bool = find_all_ret_expressions(cx, closure_expr, |ret_expr| {
if_chain! {
- if !in_macro(ret_expr.span);
+ if !ret_expr.span.from_expansion();
if let hir::ExprKind::Call(func_path, [arg]) = ret_expr.kind;
if let hir::ExprKind::Path(QPath::Resolved(_, path)) = func_path.kind;
if Self::is_variant(cx, path.res);
use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
use clippy_utils::ty::{contains_adt_constructor, contains_ty, implements_trait, is_copy, is_type_diagnostic_item};
-use clippy_utils::{contains_return, get_trait_def_id, in_macro, iter_input_pats, meets_msrv, msrvs, paths, return_ty};
+use clippy_utils::{contains_return, get_trait_def_id, iter_input_pats, meets_msrv, msrvs, paths, return_ty};
use if_chain::if_chain;
use rustc_hir as hir;
use rustc_hir::def::Res;
impl<'tcx> LateLintPass<'tcx> for Methods {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
- if in_macro(expr.span) {
+ if expr.span.from_expansion() {
return;
}
use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::in_macro;
use if_chain::if_chain;
use rustc_ast::ast::{BindingMode, Lifetime, Mutability, Param, PatKind, Path, TyKind};
use rustc_errors::Applicability;
let self_param = match (binding_mode, mutbl) {
(Mode::Ref(None), Mutability::Mut) => "&mut self".to_string(),
(Mode::Ref(Some(lifetime)), Mutability::Mut) => {
- if in_macro(lifetime.ident.span) {
+ if lifetime.ident.span.from_expansion() {
applicability = Applicability::HasPlaceholders;
"&'_ mut self".to_string()
} else {
},
(Mode::Ref(None), Mutability::Not) => "&self".to_string(),
(Mode::Ref(Some(lifetime)), Mutability::Not) => {
- if in_macro(lifetime.ident.span) {
+ if lifetime.ident.span.from_expansion() {
applicability = Applicability::HasPlaceholders;
"&'_ self".to_string()
} else {
impl EarlyLintPass for NeedlessArbitrarySelfType {
fn check_param(&mut self, cx: &EarlyContext<'_>, p: &Param) {
// Bail out if the parameter it's not a receiver or was not written by the user
- if !p.is_self() || in_macro(p.span) {
+ if !p.is_self() || p.span.from_expansion() {
return;
}
use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::in_macro;
use clippy_utils::source::snippet_opt;
use if_chain::if_chain;
use rustc_errors::Applicability;
fn is_bitwise_operation(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
let ty = cx.typeck_results().expr_ty(expr);
if_chain! {
- if !in_macro(expr.span);
+ if !expr.span.from_expansion();
if let (&ExprKind::Binary(ref op, _, right), &ty::Bool) = (&expr.kind, &ty.kind());
if op.node == BinOpKind::BitAnd || op.node == BinOpKind::BitOr;
if let ExprKind::Call(..) | ExprKind::MethodCall(..) | ExprKind::Binary(..) | ExprKind::Unary(..) = right.kind;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::{snippet_opt, snippet_with_applicability, snippet_with_context};
-use clippy_utils::{get_parent_expr, in_macro, path_to_local};
+use clippy_utils::{get_parent_expr, path_to_local};
use if_chain::if_chain;
use rustc_ast::util::parser::PREC_POSTFIX;
use rustc_data_structures::fx::FxIndexMap;
if let Some(opt_prev_pat) = self.ref_locals.get_mut(&id) {
// This binding id has been seen before. Add this pattern to the list of changes.
if let Some(prev_pat) = opt_prev_pat {
- if in_macro(pat.span) {
+ if pat.span.from_expansion() {
// Doesn't match the context of the previous pattern. Can't lint here.
*opt_prev_pat = None;
} else {
}
if_chain! {
- if !in_macro(pat.span);
+ if !pat.span.from_expansion();
if let ty::Ref(_, tam, _) = *cx.typeck_results().pat_ty(pat).kind();
// only lint immutable refs, because borrowed `&mut T` cannot be moved out
if let ty::Ref(_, _, Mutability::Not) = *tam.kind();
span,
kind: ExprKind::Unary(UnOp::Deref, _),
..
- }) if !in_macro(span) => {
+ }) if !span.from_expansion() => {
// Remove explicit deref.
let snip = snippet_with_context(cx, e.span, span.ctxt(), "..", &mut pat.app).0;
pat.replacements.push((span, snip.into()));
},
- Some(parent) if !in_macro(parent.span) => {
+ Some(parent) if !parent.span.from_expansion() => {
// Double reference might be needed at this point.
if parent.precedence().order() == PREC_POSTFIX {
// Parentheses would be needed here, don't lint.
pat.replacements.push((e.span, format!("&{}", snip)));
}
},
- _ if !in_macro(e.span) => {
+ _ if !e.span.from_expansion() => {
// Double reference might be needed at this point.
pat.always_deref = false;
let snip = snippet_with_applicability(cx, e.span, "..", &mut pat.app);
use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::in_macro;
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::is_type_diagnostic_item;
use rustc_errors::Applicability;
impl<'tcx> LateLintPass<'tcx> for OptionNeedlessDeref {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
- if expr.span.from_expansion() || in_macro(expr.span) {
+ if expr.span.from_expansion() {
return;
}
let typeck = cx.typeck_results();
hash::{Hash, Hasher},
};
-use clippy_utils::{diagnostics::span_lint_and_help, in_macro, is_direct_expn_of, source::snippet_opt};
+use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::source::snippet_opt;
use if_chain::if_chain;
use rustc_ast::ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir::def_id::DefId;
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
-use rustc_span::Span;
+use rustc_span::hygiene::{ExpnKind, MacroKind};
+use rustc_span::{Span, Symbol};
use serde::{de, Deserialize};
declare_clippy_lint! {
const BRACES: &[(&str, &str)] = &[("(", ")"), ("{", "}"), ("[", "]")];
/// The (name, (open brace, close brace), source snippet)
-type MacroInfo<'a> = (&'a str, &'a (String, String), String);
+type MacroInfo<'a> = (Symbol, &'a (String, String), String);
#[derive(Clone, Debug, Default)]
pub struct MacroBraces {
fn is_offending_macro<'a>(cx: &EarlyContext<'_>, span: Span, mac_braces: &'a MacroBraces) -> Option<MacroInfo<'a>> {
let unnested_or_local = || {
- let nested = in_macro(span.ctxt().outer_expn_data().call_site);
- !nested
+ !span.ctxt().outer_expn_data().call_site.from_expansion()
|| span
.macro_backtrace()
.last()
.map_or(false, |e| e.macro_def_id.map_or(false, DefId::is_local))
};
if_chain! {
- // Make sure we are only one level deep otherwise there are to many FP's
- if in_macro(span);
- if let Some((name, braces)) = find_matching_macro(span, &mac_braces.macro_braces);
+ if let ExpnKind::Macro(MacroKind::Bang, mac_name) = span.ctxt().outer_expn_data().kind;
+ let name = &*mac_name.as_str();
+ if let Some(braces) = mac_braces.macro_braces.get(name);
if let Some(snip) = snippet_opt(cx, span.ctxt().outer_expn_data().call_site);
// we must check only invocation sites
// https://github.com/rust-lang/rust-clippy/issues/7422
if !c.starts_with(&format!("{}!{}", name, braces.0));
if !mac_braces.done.contains(&span.ctxt().outer_expn_data().call_site);
then {
- Some((name, braces, snip))
+ Some((mac_name, braces, snip))
} else {
None
}
}
}
-fn emit_help(cx: &EarlyContext<'_>, snip: String, braces: &(String, String), name: &str, span: Span) {
+fn emit_help(cx: &EarlyContext<'_>, snip: String, braces: &(String, String), name: Symbol, span: Span) {
let with_space = &format!("! {}", braces.0);
let without_space = &format!("!{}", braces.0);
let mut help = snip;
);
}
-fn find_matching_macro(
- span: Span,
- braces: &FxHashMap<String, (String, String)>,
-) -> Option<(&String, &(String, String))> {
- braces
- .iter()
- .find(|(macro_name, _)| is_direct_expn_of(span, macro_name).is_some())
-}
-
fn macro_braces(conf: FxHashSet<MacroMatcher>) -> FxHashMap<String, (String, String)> {
let mut braces = vec![
macro_matcher!(
use clippy_utils::sugg::Sugg;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{
- can_move_expr_to_closure, eager_or_lazy, in_constant, in_macro, is_else_clause, is_lang_ctor, peel_hir_expr_while,
+ can_move_expr_to_closure, eager_or_lazy, in_constant, is_else_clause, is_lang_ctor, peel_hir_expr_while,
CaptureKind,
};
use if_chain::if_chain;
/// this construct is found, or None if this construct is not found.
fn detect_option_if_let_else<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> Option<OptionIfLetElseOccurence> {
if_chain! {
- if !in_macro(expr.span); // Don't lint macros, because it behaves weirdly
+ if !expr.span.from_expansion(); // Don't lint macros, because it behaves weirdly
if !in_constant(cx, expr.hir_id);
if let Some(higher::IfLet { let_pat, let_expr, if_then, if_else: Some(if_else) })
= higher::IfLet::hir(cx, expr);
use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::in_macro;
use clippy_utils::source::snippet_opt;
use if_chain::if_chain;
use rustc_errors::Applicability;
impl LateLintPass<'_> for PtrEq {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
- if in_macro(expr.span) {
+ if expr.span.from_expansion() {
return;
}
use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::get_parent_expr;
use clippy_utils::source::snippet_with_context;
use clippy_utils::ty::is_type_lang_item;
-use clippy_utils::{get_parent_expr, in_macro};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability};
impl LateLintPass<'_> for RedundantSlicing {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
- if in_macro(expr.span) {
+ if expr.span.from_expansion() {
return;
}
use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::in_macro;
use clippy_utils::source::{snippet_opt, snippet_with_applicability};
use clippy_utils::sugg::Sugg;
use if_chain::if_chain;
if_chain! {
if let ExprKind::Unary(UnOp::Deref, ref deref_target) = e.kind;
if let ExprKind::AddrOf(_, ref mutability, ref addrof_target) = without_parens(deref_target).kind;
- if !in_macro(addrof_target.span);
+ if !addrof_target.span.from_expansion();
then {
let mut applicability = Applicability::MachineApplicable;
let sugg = if e.span.from_expansion() {
use clippy_utils::consts::{constant_context, Constant};
use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::in_macro;
use clippy_utils::source::snippet;
use clippy_utils::ty::is_type_diagnostic_item;
use if_chain::if_chain;
if let ExprKind::MethodCall(path, _, [receiver, count], _) = &expr.kind;
if path.ident.name == sym!(repeat);
if constant_context(cx, cx.typeck_results()).expr(count) == Some(Constant::Int(1));
- if !in_macro(receiver.span);
+ if !receiver.span.from_expansion();
then {
let ty = cx.typeck_results().expr_ty(receiver).peel_refs();
if ty.is_str() {
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::source::snippet_opt;
-use clippy_utils::{fn_def_id, in_macro, path_to_local_id};
+use clippy_utils::{fn_def_id, path_to_local_id};
use if_chain::if_chain;
use rustc_ast::ast::Attribute;
use rustc_errors::Applicability;
if !last_statement_borrows(cx, initexpr);
if !in_external_macro(cx.sess(), initexpr.span);
if !in_external_macro(cx.sess(), retexpr.span);
- if !in_external_macro(cx.sess(), local.span);
- if !in_macro(local.span);
+ if !local.span.from_expansion();
then {
span_lint_and_then(
cx,
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
-use clippy_utils::in_macro;
use rustc_ast::{ptr::P, Crate, Item, ItemKind, MacroDef, ModKind, UseTreeKind, VisibilityKind};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass};
single_use_usages: &mut Vec<(Symbol, Span, bool)>,
macros: &mut Vec<Symbol>,
) {
- if in_macro(item.span) || item.vis.kind.is_pub() {
+ if item.span.from_expansion() || item.vis.kind.is_pub() {
return;
}
use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::in_macro;
use clippy_utils::paths;
use clippy_utils::source::snippet_with_macro_callsite;
use clippy_utils::ty::{is_type_diagnostic_item, is_type_ref_to_diagnostic_item};
impl LateLintPass<'tcx> for StrlenOnCStrings {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
- if in_macro(expr.span) {
+ if expr.span.from_expansion() {
return;
}
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::source::{snippet, snippet_with_applicability};
-use clippy_utils::{in_macro, SpanlessHash};
+use clippy_utils::SpanlessHash;
use if_chain::if_chain;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::unhash::UnhashMap;
impl TraitBounds {
fn check_type_repetition(self, cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
- if in_macro(gen.span) {
+ if gen.span.from_expansion() {
return;
}
let hash = |ty| -> u64 {
if_chain! {
if let WherePredicate::BoundPredicate(ref p) = bound;
if p.bounds.len() as u64 <= self.max_trait_bounds;
- if !in_macro(p.span);
+ if !p.span.from_expansion();
let h = hash(p.bounded_ty);
if let Some(ref v) = map.insert(h, p.bounds.iter().collect::<Vec<_>>());
}
fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
- if in_macro(gen.span) || gen.params.is_empty() || gen.where_clause.predicates.is_empty() {
+ if gen.span.from_expansion() || gen.params.is_empty() || gen.where_clause.predicates.is_empty() {
return;
}
for predicate in gen.where_clause.predicates {
if_chain! {
if let WherePredicate::BoundPredicate(ref bound_predicate) = predicate;
- if !in_macro(bound_predicate.span);
+ if !bound_predicate.span.from_expansion();
if let TyKind::Path(QPath::Resolved(_, Path { segments, .. })) = bound_predicate.bounded_ty.kind;
if let Some(segment) = segments.first();
if let Some(trait_resolutions_direct) = map.get(&segment.ident);
use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::{snippet, snippet_with_macro_callsite};
+use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{differing_macro_contexts, get_parent_expr, in_macro, is_lang_ctor, match_def_path, paths};
+use clippy_utils::{get_parent_expr, is_lang_ctor, match_def_path, paths};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::LangItem::ResultErr;
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, Ty};
use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::sym;
+use rustc_span::{hygiene, sym};
declare_clippy_lint! {
/// ### What it does
};
let expr_err_ty = cx.typeck_results().expr_ty(err_arg);
- let differing_contexts = differing_macro_contexts(expr.span, err_arg.span);
-
- let origin_snippet = if in_macro(expr.span) && in_macro(err_arg.span) && differing_contexts {
- snippet(cx, err_arg.span.ctxt().outer_expn_data().call_site, "_")
- } else if err_arg.span.from_expansion() && !in_macro(expr.span) {
- snippet_with_macro_callsite(cx, err_arg.span, "_")
- } else {
- snippet(cx, err_arg.span, "_")
- };
+ let span = hygiene::walk_chain(err_arg.span, try_arg.span.ctxt());
+ let mut applicability = Applicability::MachineApplicable;
+ let origin_snippet = snippet_with_applicability(cx, span, "_", &mut applicability);
let ret_prefix = if get_parent_expr(cx, expr).map_or(false, |e| matches!(e.kind, ExprKind::Ret(_))) {
"" // already returns
} else {
"returning an `Err(_)` with the `?` operator",
"try this",
suggestion,
- Applicability::MachineApplicable
+ applicability,
);
}
}
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
+use clippy_utils::is_lint_allowed;
use clippy_utils::source::{indent_of, reindent_multiline, snippet};
-use clippy_utils::{in_macro, is_lint_allowed};
use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
use rustc_hir::{Block, BlockCheckMode, Expr, ExprKind, HirId, Local, UnsafeSource};
let enclosing_scope_span = map.opt_span(enclosing_hir_id)?;
- let between_span = if in_macro(block_span) {
+ let between_span = if block_span.from_expansion() {
self.macro_expansion = true;
enclosing_scope_span.with_hi(block_span.hi())
} else {
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet;
-use clippy_utils::{contains_return, in_macro, is_lang_ctor, return_ty, visitors::find_all_ret_expressions};
+use clippy_utils::{contains_return, is_lang_ctor, return_ty, visitors::find_all_ret_expressions};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::intravisit::FnKind;
let mut suggs = Vec::new();
let can_sugg = find_all_ret_expressions(cx, &body.value, |ret_expr| {
if_chain! {
- if !in_macro(ret_expr.span);
+ if !ret_expr.span.from_expansion();
// Check if a function call.
if let ExprKind::Call(func, [arg]) = ret_expr.kind;
// Check if OPTION_SOME or RESULT_OK, depending on return type.
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::ty::same_type_and_consts;
-use clippy_utils::{in_macro, meets_msrv, msrvs};
+use clippy_utils::{meets_msrv, msrvs};
use if_chain::if_chain;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>) {
if_chain! {
- if !in_macro(hir_ty.span);
+ if !hir_ty.span.from_expansion();
if meets_msrv(self.msrv.as_ref(), &msrvs::TYPE_ALIAS_ENUM_VARIANTS);
if let Some(&StackItem::Check {
impl_id,
};
if same_type_and_consts(ty, cx.tcx.type_of(impl_id));
let hir = cx.tcx.hir();
- let id = hir.get_parent_node(hir_ty.hir_id);
- if !hir.opt_span(id).map_or(false, in_macro);
+ // prevents false positive on `#[derive(serde::Deserialize)]`
+ if !hir.span(hir.get_parent_node(hir_ty.hir_id)).in_derive_expansion();
then {
span_lint(cx, hir_ty.span);
}
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
if_chain! {
- if !in_macro(expr.span);
+ if !expr.span.from_expansion();
if meets_msrv(self.msrv.as_ref(), &msrvs::TYPE_ALIAS_ENUM_VARIANTS);
if let Some(&StackItem::Check { impl_id, .. }) = self.stack.last();
if cx.typeck_results().expr_ty(expr) == cx.tcx.type_of(impl_id);
use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::is_test_module_or_function;
use clippy_utils::source::{snippet, snippet_with_applicability};
-use clippy_utils::{in_macro, is_test_module_or_function};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{
impl WildcardImports {
fn check_exceptions(&self, item: &Item<'_>, segments: &[PathSegment<'_>]) -> bool {
- in_macro(item.span)
+ item.span.from_expansion()
|| is_prelude_import(segments)
|| (is_super_only_import(segments) && self.test_modules_deep > 0)
}
false
}
-/// Returns `true` if this `span` was expanded by any macro.
-#[must_use]
-pub fn in_macro(span: Span) -> bool {
- span.from_expansion() && !matches!(span.ctxt().outer_expn_data().kind, ExpnKind::Desugaring(..))
-}
-
pub fn is_unit_expr(expr: &Expr<'_>) -> bool {
matches!(
expr.kind,
// desugaring, as this will detect a break if there's a while loop
// or a for loop inside the expression.
_ => {
- if utils::in_macro(ex.span) {
+ if ex.span.from_expansion() {
self.seen_return_break_continue = true;
} else {
rustc_hir::intravisit::walk_expr(self, ex);
#![warn(clippy::if_chain_style)]
-#![allow(clippy::no_effect)]
+#![allow(clippy::no_effect, clippy::nonminimal_bool)]
extern crate if_chain;
// [edition2018] edition:2018
// [edition2021] edition:2021
// run-rustfix
+
#![warn(clippy::manual_assert)]
+#![allow(clippy::nonminimal_bool)]
fn main() {
let a = vec![1, 2, 3];
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:22:5
+ --> $DIR/manual_assert.rs:24:5
|
LL | / if !a.is_empty() {
LL | | panic!("qaqaq{:?}", a);
= note: `-D clippy::manual-assert` implied by `-D warnings`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:25:5
+ --> $DIR/manual_assert.rs:27:5
|
LL | / if !a.is_empty() {
LL | | panic!("qwqwq");
| |_____^ help: try: `assert!(a.is_empty(), "qwqwq");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:42:5
+ --> $DIR/manual_assert.rs:44:5
|
LL | / if b.is_empty() {
LL | | panic!("panic1");
| |_____^ help: try: `assert!(!b.is_empty(), "panic1");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:45:5
+ --> $DIR/manual_assert.rs:47:5
|
LL | / if b.is_empty() && a.is_empty() {
LL | | panic!("panic2");
| |_____^ help: try: `assert!(!(b.is_empty() && a.is_empty()), "panic2");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:48:5
+ --> $DIR/manual_assert.rs:50:5
|
LL | / if a.is_empty() && !b.is_empty() {
LL | | panic!("panic3");
| |_____^ help: try: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:51:5
+ --> $DIR/manual_assert.rs:53:5
|
LL | / if b.is_empty() || a.is_empty() {
LL | | panic!("panic4");
| |_____^ help: try: `assert!(!(b.is_empty() || a.is_empty()), "panic4");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:54:5
+ --> $DIR/manual_assert.rs:56:5
|
LL | / if a.is_empty() || !b.is_empty() {
LL | | panic!("panic5");
// [edition2018] edition:2018
// [edition2021] edition:2021
// run-rustfix
+
#![warn(clippy::manual_assert)]
+#![allow(clippy::nonminimal_bool)]
fn main() {
let a = vec![1, 2, 3];
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:22:5
+ --> $DIR/manual_assert.rs:24:5
|
LL | / if !a.is_empty() {
LL | | panic!("qaqaq{:?}", a);
= note: `-D clippy::manual-assert` implied by `-D warnings`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:25:5
+ --> $DIR/manual_assert.rs:27:5
|
LL | / if !a.is_empty() {
LL | | panic!("qwqwq");
| |_____^ help: try: `assert!(a.is_empty(), "qwqwq");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:42:5
+ --> $DIR/manual_assert.rs:44:5
|
LL | / if b.is_empty() {
LL | | panic!("panic1");
| |_____^ help: try: `assert!(!b.is_empty(), "panic1");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:45:5
+ --> $DIR/manual_assert.rs:47:5
|
LL | / if b.is_empty() && a.is_empty() {
LL | | panic!("panic2");
| |_____^ help: try: `assert!(!(b.is_empty() && a.is_empty()), "panic2");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:48:5
+ --> $DIR/manual_assert.rs:50:5
|
LL | / if a.is_empty() && !b.is_empty() {
LL | | panic!("panic3");
| |_____^ help: try: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:51:5
+ --> $DIR/manual_assert.rs:53:5
|
LL | / if b.is_empty() || a.is_empty() {
LL | | panic!("panic4");
| |_____^ help: try: `assert!(!(b.is_empty() || a.is_empty()), "panic4");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:54:5
+ --> $DIR/manual_assert.rs:56:5
|
LL | / if a.is_empty() || !b.is_empty() {
LL | | panic!("panic5");
// [edition2018] edition:2018
// [edition2021] edition:2021
// run-rustfix
+
#![warn(clippy::manual_assert)]
+#![allow(clippy::nonminimal_bool)]
fn main() {
let a = vec![1, 2, 3];
// [edition2018] edition:2018
// [edition2021] edition:2021
// run-rustfix
+
#![warn(clippy::manual_assert)]
+#![allow(clippy::nonminimal_bool)]
fn main() {
let a = vec![1, 2, 3];