mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-23 05:03:21 +00:00
Prevent symbocalypse
This commit is contained in:
parent
11194e3d05
commit
f7f85a0dca
78 changed files with 686 additions and 1160 deletions
|
@ -1,13 +1,10 @@
|
|||
use crate::utils::span_lint;
|
||||
use crate::utils::sym;
|
||||
use lazy_static::lazy_static;
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_lint_pass, declare_tool_lint};
|
||||
use std::f64::consts as f64;
|
||||
use syntax::ast::{FloatTy, LitKind};
|
||||
use syntax::symbol;
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for floating point literals that approximate
|
||||
|
@ -33,27 +30,25 @@ declare_clippy_lint! {
|
|||
"the approximate of a known float constant (in `std::fXX::consts`)"
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
// Tuples are of the form (constant, name, min_digits)
|
||||
static ref KNOWN_CONSTS: [(f64, Symbol, usize); 16] = [
|
||||
(f64::E, *sym::E, 4),
|
||||
(f64::FRAC_1_PI, *sym::FRAC_1_PI, 4),
|
||||
(f64::FRAC_1_SQRT_2, *sym::FRAC_1_SQRT_2, 5),
|
||||
(f64::FRAC_2_PI, *sym::FRAC_2_PI, 5),
|
||||
(f64::FRAC_2_SQRT_PI, *sym::FRAC_2_SQRT_PI, 5),
|
||||
(f64::FRAC_PI_2, *sym::FRAC_PI_2, 5),
|
||||
(f64::FRAC_PI_3, *sym::FRAC_PI_3, 5),
|
||||
(f64::FRAC_PI_4, *sym::FRAC_PI_4, 5),
|
||||
(f64::FRAC_PI_6, *sym::FRAC_PI_6, 5),
|
||||
(f64::FRAC_PI_8, *sym::FRAC_PI_8, 5),
|
||||
(f64::LN_10, *sym::LN_10, 5),
|
||||
(f64::LN_2, *sym::LN_2, 5),
|
||||
(f64::LOG10_E, *sym::LOG10_E, 5),
|
||||
(f64::LOG2_E, *sym::LOG2_E, 5),
|
||||
(f64::PI, *sym::PI, 3),
|
||||
(f64::SQRT_2, *sym::SQRT_2, 5),
|
||||
const KNOWN_CONSTS: [(f64, &str, usize); 16] = [
|
||||
(f64::E, "E", 4),
|
||||
(f64::FRAC_1_PI, "FRAC_1_PI", 4),
|
||||
(f64::FRAC_1_SQRT_2, "FRAC_1_SQRT_2", 5),
|
||||
(f64::FRAC_2_PI, "FRAC_2_PI", 5),
|
||||
(f64::FRAC_2_SQRT_PI, "FRAC_2_SQRT_PI", 5),
|
||||
(f64::FRAC_PI_2, "FRAC_PI_2", 5),
|
||||
(f64::FRAC_PI_3, "FRAC_PI_3", 5),
|
||||
(f64::FRAC_PI_4, "FRAC_PI_4", 5),
|
||||
(f64::FRAC_PI_6, "FRAC_PI_6", 5),
|
||||
(f64::FRAC_PI_8, "FRAC_PI_8", 5),
|
||||
(f64::LN_10, "LN_10", 5),
|
||||
(f64::LN_2, "LN_2", 5),
|
||||
(f64::LOG10_E, "LOG10_E", 5),
|
||||
(f64::LOG2_E, "LOG2_E", 5),
|
||||
(f64::PI, "PI", 3),
|
||||
(f64::SQRT_2, "SQRT_2", 5),
|
||||
];
|
||||
}
|
||||
|
||||
declare_lint_pass!(ApproxConstant => [APPROX_CONSTANT]);
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ use rustc::{declare_lint_pass, declare_tool_lint};
|
|||
use syntax_pos::Span;
|
||||
|
||||
use crate::consts::{constant, Constant};
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{in_macro_or_desugar, is_direct_expn_of, span_help_and_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -41,9 +40,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssertionsOnConstants {
|
|||
!in_macro_or_desugar(span)
|
||||
};
|
||||
if_chain! {
|
||||
if let Some(assert_span) = is_direct_expn_of(e.span, *sym::assert);
|
||||
if let Some(assert_span) = is_direct_expn_of(e.span, "assert");
|
||||
if !in_macro_or_desugar(assert_span)
|
||||
|| is_direct_expn_of(assert_span, *sym::debug_assert)
|
||||
|| is_direct_expn_of(assert_span, "debug_assert")
|
||||
.map_or(false, debug_assert_not_in_macro_or_desugar);
|
||||
if let ExprKind::Unary(_, ref lit) = e.node;
|
||||
if let Some(bool_const) = constant(cx, cx.tables, lit);
|
||||
|
|
|
@ -9,7 +9,6 @@ use crate::utils::{
|
|||
get_trait_def_id, implements_trait, snippet_opt, span_lint_and_then, trait_ref_of_method, SpanlessEq,
|
||||
};
|
||||
use crate::utils::{higher, sugg};
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `a = a op b` or `a = b commutative_op a`
|
||||
|
@ -89,11 +88,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
|
|||
$($trait_name:ident),+) => {
|
||||
match $op {
|
||||
$(hir::BinOpKind::$trait_name => {
|
||||
let [krate, module] = *crate::utils::paths::OPS_MODULE;
|
||||
let ident = {
|
||||
*crate::utils::sym::assign::$trait_name
|
||||
};
|
||||
let path: [Symbol; 3] = [krate, module, ident];
|
||||
let [krate, module] = crate::utils::paths::OPS_MODULE;
|
||||
let path: [&str; 3] = [krate, module, concat!(stringify!($trait_name), "Assign")];
|
||||
let trait_id = if let Some(trait_id) = get_trait_def_id($cx, &path) {
|
||||
trait_id
|
||||
} else {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
//! checks for attributes
|
||||
|
||||
use crate::reexport::*;
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{
|
||||
in_macro_or_desugar, is_present_in_source, last_line_of_span, match_def_path, paths, snippet_opt, span_lint,
|
||||
span_lint_and_sugg, span_lint_and_then, without_block_comments,
|
||||
|
@ -18,7 +17,7 @@ use rustc_errors::Applicability;
|
|||
use semver::Version;
|
||||
use syntax::ast::{AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
|
||||
use syntax::source_map::Span;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax_pos::symbol::Symbol;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for items annotated with `#[inline(always)]`,
|
||||
|
@ -207,14 +206,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Attributes {
|
|||
},
|
||||
_ => {},
|
||||
}
|
||||
if items.is_empty() || !attr.check_name(*sym::deprecated) {
|
||||
if items.is_empty() || !attr.check_name(sym!(deprecated)) {
|
||||
return;
|
||||
}
|
||||
for item in items {
|
||||
if_chain! {
|
||||
if let NestedMetaItem::MetaItem(mi) = &item;
|
||||
if let MetaItemKind::NameValue(lit) = &mi.node;
|
||||
if mi.check_name(*sym::since);
|
||||
if mi.check_name(sym!(since));
|
||||
then {
|
||||
check_semver(cx, item.span(), lit);
|
||||
}
|
||||
|
@ -230,7 +229,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Attributes {
|
|||
}
|
||||
match item.node {
|
||||
ItemKind::ExternCrate(..) | ItemKind::Use(..) => {
|
||||
let skip_unused_imports = item.attrs.iter().any(|attr| attr.check_name(*sym::macro_use));
|
||||
let skip_unused_imports = item.attrs.iter().any(|attr| attr.check_name(sym!(macro_use)));
|
||||
|
||||
for attr in &item.attrs {
|
||||
if in_external_macro(cx.sess(), attr.span) {
|
||||
|
@ -245,17 +244,17 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Attributes {
|
|||
for lint in lint_list {
|
||||
match item.node {
|
||||
ItemKind::Use(..) => {
|
||||
if is_word(lint, *sym::unused_imports)
|
||||
|| is_word(lint, *sym::deprecated)
|
||||
if is_word(lint, sym!(unused_imports))
|
||||
|| is_word(lint, sym!(deprecated))
|
||||
{
|
||||
return;
|
||||
}
|
||||
},
|
||||
ItemKind::ExternCrate(..) => {
|
||||
if is_word(lint, *sym::unused_imports) && skip_unused_imports {
|
||||
if is_word(lint, sym!(unused_imports)) && skip_unused_imports {
|
||||
return;
|
||||
}
|
||||
if is_word(lint, *sym::unused_extern_crates) {
|
||||
if is_word(lint, sym!(unused_extern_crates)) {
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
@ -399,7 +398,7 @@ fn is_relevant_expr(cx: &LateContext<'_, '_>, tables: &ty::TypeckTables<'_>, exp
|
|||
ExprKind::Call(path_expr, _) => {
|
||||
if let ExprKind::Path(qpath) = &path_expr.node {
|
||||
if let Some(fun_id) = tables.qpath_res(qpath, path_expr.hir_id).opt_def_id() {
|
||||
!match_def_path(cx, fun_id, &*paths::BEGIN_PANIC)
|
||||
!match_def_path(cx, fun_id, &paths::BEGIN_PANIC)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
|
@ -445,10 +444,10 @@ fn check_attrs(cx: &LateContext<'_, '_>, span: Span, name: Name, attrs: &[Attrib
|
|||
}
|
||||
|
||||
if let Some(values) = attr.meta_item_list() {
|
||||
if values.len() != 1 || !attr.check_name(*sym::inline) {
|
||||
if values.len() != 1 || !attr.check_name(sym!(inline)) {
|
||||
continue;
|
||||
}
|
||||
if is_word(&values[0], *sym::always) {
|
||||
if is_word(&values[0], sym!(always)) {
|
||||
span_lint(
|
||||
cx,
|
||||
INLINE_ALWAYS,
|
||||
|
@ -491,16 +490,16 @@ impl EarlyLintPass for DeprecatedCfgAttribute {
|
|||
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {
|
||||
if_chain! {
|
||||
// check cfg_attr
|
||||
if attr.check_name(*sym::cfg_attr);
|
||||
if attr.check_name(sym!(cfg_attr));
|
||||
if let Some(items) = attr.meta_item_list();
|
||||
if items.len() == 2;
|
||||
// check for `rustfmt`
|
||||
if let Some(feature_item) = items[0].meta_item();
|
||||
if feature_item.check_name(*sym::rustfmt);
|
||||
if feature_item.check_name(sym!(rustfmt));
|
||||
// check for `rustfmt_skip` and `rustfmt::skip`
|
||||
if let Some(skip_item) = &items[1].meta_item();
|
||||
if skip_item.check_name(*sym::rustfmt_skip) ||
|
||||
skip_item.path.segments.last().expect("empty path in attribute").ident.name == *sym::skip;
|
||||
if skip_item.check_name(sym!(rustfmt_skip)) ||
|
||||
skip_item.path.segments.last().expect("empty path in attribute").ident.name == sym!(skip);
|
||||
// Only lint outer attributes, because custom inner attributes are unstable
|
||||
// Tracking issue: https://github.com/rust-lang/rust/issues/54726
|
||||
if let AttrStyle::Outer = attr.style;
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
use crate::utils::sym;
|
||||
use crate::utils::{
|
||||
get_trait_def_id, implements_trait, in_macro, in_macro_or_desugar, match_type, paths, snippet_opt,
|
||||
span_lint_and_then, SpanlessEq,
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
use rustc::hir::intravisit::*;
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
|
@ -12,7 +10,6 @@ use rustc_data_structures::thin_vec::ThinVec;
|
|||
use rustc_errors::Applicability;
|
||||
use syntax::ast::LitKind;
|
||||
use syntax::source_map::{dummy_spanned, Span, DUMMY_SP};
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for boolean expressions that can be written more
|
||||
|
@ -52,13 +49,11 @@ declare_clippy_lint! {
|
|||
"boolean expressions that contain terminals which can be eliminated"
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
// For each pairs, both orders are considered.
|
||||
static ref METHODS_WITH_NEGATION: [(Symbol, Symbol); 2] = [
|
||||
(*sym::is_some, *sym::is_none),
|
||||
(*sym::is_err, *sym::is_ok),
|
||||
const METHODS_WITH_NEGATION: [(&str, &str); 2] = [
|
||||
("is_some", "is_none"),
|
||||
("is_err", "is_ok"),
|
||||
];
|
||||
}
|
||||
|
||||
declare_lint_pass!(NonminimalBool => [NONMINIMAL_BOOL, LOGIC_BUG]);
|
||||
|
||||
|
@ -195,8 +190,8 @@ impl<'a, 'tcx, 'v> SuggestContext<'a, 'tcx, 'v> {
|
|||
},
|
||||
ExprKind::MethodCall(path, _, args) if args.len() == 1 => {
|
||||
let type_of_receiver = self.cx.tables.expr_ty(&args[0]);
|
||||
if !match_type(self.cx, type_of_receiver, &*paths::OPTION)
|
||||
&& !match_type(self.cx, type_of_receiver, &*paths::RESULT)
|
||||
if !match_type(self.cx, type_of_receiver, &paths::OPTION)
|
||||
&& !match_type(self.cx, type_of_receiver, &paths::RESULT)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
@ -204,7 +199,7 @@ impl<'a, 'tcx, 'v> SuggestContext<'a, 'tcx, 'v> {
|
|||
.iter()
|
||||
.cloned()
|
||||
.flat_map(|(a, b)| vec![(a, b), (b, a)])
|
||||
.find(|&(a, _)| a == path.ident.name)
|
||||
.find(|&(a, _)| a == path.ident.name.as_str())
|
||||
.and_then(|(_, neg_method)| Some(format!("{}.{}()", self.snip(&args[0])?, neg_method)))
|
||||
},
|
||||
_ => None,
|
||||
|
@ -474,5 +469,5 @@ impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> {
|
|||
|
||||
fn implements_ord<'a, 'tcx>(cx: &'a LateContext<'a, 'tcx>, expr: &Expr) -> bool {
|
||||
let ty = cx.tables.expr_ty(expr);
|
||||
get_trait_def_id(cx, &*paths::ORD).map_or(false, |id| implements_trait(cx, ty, id, &[]))
|
||||
get_trait_def_id(cx, &paths::ORD).map_or(false, |id| implements_trait(cx, ty, id, &[]))
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::utils::sym;
|
||||
use crate::utils::{
|
||||
contains_name, get_pat_name, match_type, paths, single_segment_path, snippet_with_applicability,
|
||||
span_lint_and_sugg, walk_ptrs_ty,
|
||||
|
@ -38,10 +37,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount {
|
|||
fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr) {
|
||||
if_chain! {
|
||||
if let ExprKind::MethodCall(ref count, _, ref count_args) = expr.node;
|
||||
if count.ident.name == *sym::count;
|
||||
if count.ident.name == sym!(count);
|
||||
if count_args.len() == 1;
|
||||
if let ExprKind::MethodCall(ref filter, _, ref filter_args) = count_args[0].node;
|
||||
if filter.ident.name == *sym::filter;
|
||||
if filter.ident.name == sym!(filter);
|
||||
if filter_args.len() == 2;
|
||||
if let ExprKind::Closure(_, _, body_id, _, _) = filter_args[1].node;
|
||||
then {
|
||||
|
@ -53,7 +52,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount {
|
|||
if op.node == BinOpKind::Eq;
|
||||
if match_type(cx,
|
||||
walk_ptrs_ty(cx.tables.expr_ty(&filter_args[0])),
|
||||
&*paths::SLICE_ITER);
|
||||
&paths::SLICE_ITER);
|
||||
then {
|
||||
let needle = match get_path_name(l) {
|
||||
Some(name) if check_arg(name, argname, r) => r,
|
||||
|
@ -68,7 +67,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount {
|
|||
let haystack = if let ExprKind::MethodCall(ref path, _, ref args) =
|
||||
filter_args[0].node {
|
||||
let p = path.ident.name;
|
||||
if (p == *sym::iter || p == *sym::iter_mut) && args.len() == 1 {
|
||||
if (p == sym!(iter) || p == sym!(iter_mut)) && args.len() == 1 {
|
||||
&args[0]
|
||||
} else {
|
||||
&filter_args[0]
|
||||
|
|
|
@ -9,7 +9,6 @@ use rustc::{declare_tool_lint, impl_lint_pass};
|
|||
use syntax::ast::Attribute;
|
||||
use syntax::source_map::Span;
|
||||
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{in_macro_or_desugar, is_allowed, match_type, paths, span_help_and_lint, LimitStack};
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -72,7 +71,7 @@ impl CognitiveComplexity {
|
|||
..
|
||||
} = helper;
|
||||
let ret_ty = cx.tables.node_type(expr.hir_id);
|
||||
let ret_adjust = if match_type(cx, ret_ty, &*paths::RESULT) {
|
||||
let ret_adjust = if match_type(cx, ret_ty, &paths::RESULT) {
|
||||
returns
|
||||
} else {
|
||||
returns / 2
|
||||
|
@ -119,7 +118,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CognitiveComplexity {
|
|||
hir_id: HirId,
|
||||
) {
|
||||
let def_id = cx.tcx.hir().local_def_id_from_hir_id(hir_id);
|
||||
if !cx.tcx.has_attr(def_id, *sym::test) {
|
||||
if !cx.tcx.has_attr(def_id, sym!(test)) {
|
||||
self.check(cx, body, span);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CopyIterator {
|
|||
if let ItemKind::Impl(_, _, _, _, Some(ref trait_ref), _, _) = item.node {
|
||||
let ty = cx.tcx.type_of(cx.tcx.hir().local_def_id_from_hir_id(item.hir_id));
|
||||
|
||||
if is_copy(cx, ty) && match_path(&trait_ref.path, &*paths::ITERATOR) {
|
||||
if is_copy(cx, ty) && match_path(&trait_ref.path, &paths::ITERATOR) {
|
||||
span_note_and_lint(
|
||||
cx,
|
||||
COPY_ITERATOR,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::utils::sym;
|
||||
use crate::utils::{snippet_opt, span_help_and_lint, span_lint_and_sugg};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_lint_pass, declare_tool_lint};
|
||||
|
@ -32,7 +31,7 @@ declare_lint_pass!(DbgMacro => [DBG_MACRO]);
|
|||
|
||||
impl EarlyLintPass for DbgMacro {
|
||||
fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::Mac) {
|
||||
if mac.node.path == *sym::dbg {
|
||||
if mac.node.path == sym!(dbg) {
|
||||
if let Some(sugg) = tts_span(mac.node.tts.clone()).and_then(|span| snippet_opt(cx, span)) {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
|
|
|
@ -37,7 +37,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DefaultTraitAccess {
|
|||
if !any_parent_is_automatically_derived(cx.tcx, expr.hir_id);
|
||||
if let ExprKind::Path(ref qpath) = path.node;
|
||||
if let Some(def_id) = cx.tables.qpath_res(qpath, path.hir_id).opt_def_id();
|
||||
if match_def_path(cx, def_id, &*paths::DEFAULT_TRAIT_METHOD);
|
||||
if match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD);
|
||||
then {
|
||||
match qpath {
|
||||
QPath::Resolved(..) => {
|
||||
|
|
|
@ -88,7 +88,7 @@ fn check_hash_peq<'a, 'tcx>(
|
|||
hash_is_automatically_derived: bool,
|
||||
) {
|
||||
if_chain! {
|
||||
if match_path(&trait_ref.path, &*paths::HASH);
|
||||
if match_path(&trait_ref.path, &paths::HASH);
|
||||
if let Some(peq_trait_def_id) = cx.tcx.lang_items().eq_trait();
|
||||
then {
|
||||
// Look for the PartialEq implementations for `ty`
|
||||
|
@ -129,7 +129,7 @@ fn check_hash_peq<'a, 'tcx>(
|
|||
|
||||
/// Implementation of the `EXPL_IMPL_CLONE_ON_COPY` lint.
|
||||
fn check_copy_clone<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, item: &Item, trait_ref: &TraitRef, ty: Ty<'tcx>) {
|
||||
if match_path(&trait_ref.path, &*paths::CLONE_TRAIT) {
|
||||
if match_path(&trait_ref.path, &paths::CLONE_TRAIT) {
|
||||
if !is_copy(cx, ty) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use crate::utils::span_lint;
|
||||
use crate::utils::sym;
|
||||
use itertools::Itertools;
|
||||
use pulldown_cmark;
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
|
||||
|
@ -128,7 +127,7 @@ pub fn check_attrs<'a>(cx: &EarlyContext<'_>, valid_idents: &FxHashSet<String>,
|
|||
spans.extend_from_slice(¤t_spans);
|
||||
doc.push_str(¤t);
|
||||
}
|
||||
} else if attr.check_name(*sym::doc) {
|
||||
} else if attr.check_name(sym!(doc)) {
|
||||
// ignore mix of sugared and non-sugared doc
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ fn lint_bound<'a, 'tcx>(cx: &rustc::lint::LateContext<'a, 'tcx>, bound: &'tcx Ge
|
|||
if_chain! {
|
||||
if let GenericBound::Trait(t, _) = bound;
|
||||
if let Some(def_id) = t.trait_ref.path.res.opt_def_id();
|
||||
if match_def_path(cx, def_id, &*paths::DROP_TRAIT);
|
||||
if match_def_path(cx, def_id, &paths::DROP_TRAIT);
|
||||
then {
|
||||
span_lint(
|
||||
cx,
|
||||
|
|
|
@ -122,10 +122,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DropForgetRef {
|
|||
let arg_ty = cx.tables.expr_ty(arg);
|
||||
|
||||
if let ty::Ref(..) = arg_ty.sty {
|
||||
if match_def_path(cx, def_id, &*paths::DROP) {
|
||||
if match_def_path(cx, def_id, &paths::DROP) {
|
||||
lint = DROP_REF;
|
||||
msg = DROP_REF_SUMMARY.to_string();
|
||||
} else if match_def_path(cx, def_id, &*paths::MEM_FORGET) {
|
||||
} else if match_def_path(cx, def_id, &paths::MEM_FORGET) {
|
||||
lint = FORGET_REF;
|
||||
msg = FORGET_REF_SUMMARY.to_string();
|
||||
} else {
|
||||
|
@ -138,10 +138,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DropForgetRef {
|
|||
arg.span,
|
||||
&format!("argument has type {}", arg_ty));
|
||||
} else if is_copy(cx, arg_ty) {
|
||||
if match_def_path(cx, def_id, &*paths::DROP) {
|
||||
if match_def_path(cx, def_id, &paths::DROP) {
|
||||
lint = DROP_COPY;
|
||||
msg = DROP_COPY_SUMMARY.to_string();
|
||||
} else if match_def_path(cx, def_id, &*paths::MEM_FORGET) {
|
||||
} else if match_def_path(cx, def_id, &paths::MEM_FORGET) {
|
||||
lint = FORGET_COPY;
|
||||
msg = FORGET_COPY_SUMMARY.to_string();
|
||||
} else {
|
||||
|
|
|
@ -36,7 +36,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DurationSubsec {
|
|||
if_chain! {
|
||||
if let ExprKind::Binary(Spanned { node: BinOpKind::Div, .. }, ref left, ref right) = expr.node;
|
||||
if let ExprKind::MethodCall(ref method_path, _ , ref args) = left.node;
|
||||
if match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(&args[0])), &*paths::DURATION);
|
||||
if match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(&args[0])), &paths::DURATION);
|
||||
if let Some((Constant::Int(divisor), _)) = constant(cx, cx.tables, right);
|
||||
then {
|
||||
let suggested_fn = match (method_path.ident.as_str().as_ref(), divisor) {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::utils::sym;
|
||||
use crate::utils::SpanlessEq;
|
||||
use crate::utils::{get_item_name, higher, match_type, paths, snippet, span_lint_and_then, walk_ptrs_ty};
|
||||
use if_chain::if_chain;
|
||||
|
@ -92,16 +91,16 @@ fn check_cond<'a, 'tcx, 'b>(
|
|||
if_chain! {
|
||||
if let ExprKind::MethodCall(ref path, _, ref params) = check.node;
|
||||
if params.len() >= 2;
|
||||
if path.ident.name == *sym::contains_key;
|
||||
if path.ident.name == sym!(contains_key);
|
||||
if let ExprKind::AddrOf(_, ref key) = params[1].node;
|
||||
then {
|
||||
let map = ¶ms[0];
|
||||
let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(map));
|
||||
|
||||
return if match_type(cx, obj_ty, &*paths::BTREEMAP) {
|
||||
return if match_type(cx, obj_ty, &paths::BTREEMAP) {
|
||||
Some(("BTreeMap", map, key))
|
||||
}
|
||||
else if match_type(cx, obj_ty, &*paths::HASHMAP) {
|
||||
else if match_type(cx, obj_ty, &paths::HASHMAP) {
|
||||
Some(("HashMap", map, key))
|
||||
}
|
||||
else {
|
||||
|
@ -127,7 +126,7 @@ impl<'a, 'tcx, 'b> Visitor<'tcx> for InsertVisitor<'a, 'tcx, 'b> {
|
|||
if_chain! {
|
||||
if let ExprKind::MethodCall(ref path, _, ref params) = expr.node;
|
||||
if params.len() == 3;
|
||||
if path.ident.name == *sym::insert;
|
||||
if path.ident.name == sym!(insert);
|
||||
if get_item_name(self.cx, self.map) == get_item_name(self.cx, ¶ms[0]);
|
||||
if SpanlessEq::new(self.cx).eq_expr(self.key, ¶ms[1]);
|
||||
then {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::utils::sym;
|
||||
use crate::utils::{is_expn_of, match_def_path, paths, resolve_node, span_lint, span_lint_and_sugg};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir::*;
|
||||
|
@ -32,20 +31,20 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitWrite {
|
|||
if_chain! {
|
||||
// match call to unwrap
|
||||
if let ExprKind::MethodCall(ref unwrap_fun, _, ref unwrap_args) = expr.node;
|
||||
if unwrap_fun.ident.name == *sym::unwrap;
|
||||
if unwrap_fun.ident.name == sym!(unwrap);
|
||||
// match call to write_fmt
|
||||
if unwrap_args.len() > 0;
|
||||
if let ExprKind::MethodCall(ref write_fun, _, ref write_args) =
|
||||
unwrap_args[0].node;
|
||||
if write_fun.ident.name == *sym::write_fmt;
|
||||
if write_fun.ident.name == sym!(write_fmt);
|
||||
// match calls to std::io::stdout() / std::io::stderr ()
|
||||
if write_args.len() > 0;
|
||||
if let ExprKind::Call(ref dest_fun, _) = write_args[0].node;
|
||||
if let ExprKind::Path(ref qpath) = dest_fun.node;
|
||||
if let Some(dest_fun_id) = resolve_node(cx, qpath, dest_fun.hir_id).opt_def_id();
|
||||
if let Some(dest_name) = if match_def_path(cx, dest_fun_id, &*paths::STDOUT) {
|
||||
if let Some(dest_name) = if match_def_path(cx, dest_fun_id, &paths::STDOUT) {
|
||||
Some("stdout")
|
||||
} else if match_def_path(cx, dest_fun_id, &*paths::STDERR) {
|
||||
} else if match_def_path(cx, dest_fun_id, &paths::STDERR) {
|
||||
Some("stderr")
|
||||
} else {
|
||||
None
|
||||
|
@ -54,9 +53,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitWrite {
|
|||
let write_span = unwrap_args[0].span;
|
||||
let calling_macro =
|
||||
// ordering is important here, since `writeln!` uses `write!` internally
|
||||
if is_expn_of(write_span, *sym::writeln).is_some() {
|
||||
if is_expn_of(write_span, "writeln").is_some() {
|
||||
Some("writeln")
|
||||
} else if is_expn_of(write_span, *sym::write).is_some() {
|
||||
} else if is_expn_of(write_span, "write").is_some() {
|
||||
Some("write")
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
use crate::utils::paths::{BEGIN_PANIC, BEGIN_PANIC_FMT, FROM_TRAIT, OPTION, RESULT};
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{is_expn_of, match_def_path, method_chain_args, span_lint_and_then, walk_ptrs_ty};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::{declare_lint_pass, declare_tool_lint};
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax_pos::Span;
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -39,7 +37,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FallibleImplFrom {
|
|||
if_chain! {
|
||||
if let hir::ItemKind::Impl(.., ref impl_items) = item.node;
|
||||
if let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(impl_def_id);
|
||||
if match_def_path(cx, impl_trait_ref.def_id, &*FROM_TRAIT);
|
||||
if match_def_path(cx, impl_trait_ref.def_id, &FROM_TRAIT);
|
||||
then {
|
||||
lint_impl_body(cx, item.span, impl_items);
|
||||
}
|
||||
|
@ -64,18 +62,18 @@ fn lint_impl_body<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, impl_span: Span, impl_it
|
|||
if let ExprKind::Call(ref func_expr, _) = expr.node;
|
||||
if let ExprKind::Path(QPath::Resolved(_, ref path)) = func_expr.node;
|
||||
if let Some(path_def_id) = path.res.opt_def_id();
|
||||
if match_def_path(self.lcx, path_def_id, &*BEGIN_PANIC) ||
|
||||
match_def_path(self.lcx, path_def_id, &*BEGIN_PANIC_FMT);
|
||||
if is_expn_of(expr.span, *sym::unreachable).is_none();
|
||||
if match_def_path(self.lcx, path_def_id, &BEGIN_PANIC) ||
|
||||
match_def_path(self.lcx, path_def_id, &BEGIN_PANIC_FMT);
|
||||
if is_expn_of(expr.span, "unreachable").is_none();
|
||||
then {
|
||||
self.result.push(expr.span);
|
||||
}
|
||||
}
|
||||
|
||||
// check for `unwrap`
|
||||
if let Some(arglists) = method_chain_args(expr, &[*sym::unwrap]) {
|
||||
if let Some(arglists) = method_chain_args(expr, &["unwrap"]) {
|
||||
let reciever_ty = walk_ptrs_ty(self.tables.expr_ty(&arglists[0][0]));
|
||||
if match_type(self.lcx, reciever_ty, &*OPTION) || match_type(self.lcx, reciever_ty, &*RESULT) {
|
||||
if match_type(self.lcx, reciever_ty, &OPTION) || match_type(self.lcx, reciever_ty, &RESULT) {
|
||||
self.result.push(expr.span);
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +89,7 @@ fn lint_impl_body<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, impl_span: Span, impl_it
|
|||
|
||||
for impl_item in impl_items {
|
||||
if_chain! {
|
||||
if impl_item.ident.name == *sym::from;
|
||||
if impl_item.ident.name == sym!(from);
|
||||
if let ImplItemKind::Method(_, body_id) =
|
||||
cx.tcx.hir().impl_item(impl_item.id).node;
|
||||
then {
|
||||
|
@ -124,7 +122,7 @@ fn lint_impl_body<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, impl_span: Span, impl_it
|
|||
}
|
||||
}
|
||||
|
||||
fn match_type(cx: &LateContext<'_, '_>, ty: Ty<'_>, path: &[Symbol]) -> bool {
|
||||
fn match_type(cx: &LateContext<'_, '_>, ty: Ty<'_>, path: &[&str]) -> bool {
|
||||
match ty.sty {
|
||||
ty::Adt(adt, _) => match_def_path(cx, adt.did, path),
|
||||
_ => false,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use crate::utils::paths;
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{
|
||||
in_macro_or_desugar, is_expn_of, last_path_segment, match_def_path, match_type, resolve_node, snippet,
|
||||
span_lint_and_then, walk_ptrs_ty,
|
||||
|
@ -39,7 +38,7 @@ declare_lint_pass!(UselessFormat => [USELESS_FORMAT]);
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessFormat {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
if let Some(span) = is_expn_of(expr.span, *sym::format) {
|
||||
if let Some(span) = is_expn_of(expr.span, "format") {
|
||||
if in_macro_or_desugar(span) {
|
||||
return;
|
||||
}
|
||||
|
@ -49,10 +48,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessFormat {
|
|||
if_chain! {
|
||||
if let ExprKind::Path(ref qpath) = fun.node;
|
||||
if let Some(fun_def_id) = resolve_node(cx, qpath, fun.hir_id).opt_def_id();
|
||||
let new_v1 = match_def_path(cx, fun_def_id, &*paths::FMT_ARGUMENTS_NEWV1);
|
||||
let new_v1 = match_def_path(cx, fun_def_id, &paths::FMT_ARGUMENTS_NEWV1);
|
||||
let new_v1_fmt = match_def_path(cx,
|
||||
fun_def_id,
|
||||
&*paths::FMT_ARGUMENTS_NEWV1FORMATTED
|
||||
&paths::FMT_ARGUMENTS_NEWV1FORMATTED
|
||||
);
|
||||
if new_v1 || new_v1_fmt;
|
||||
if check_single_piece(&args[0]);
|
||||
|
@ -151,10 +150,10 @@ fn get_single_string_arg<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr) -> Option
|
|||
if args.len() == 2;
|
||||
if let ExprKind::Path(ref qpath) = args[1].node;
|
||||
if let Some(fun_def_id) = resolve_node(cx, qpath, args[1].hir_id).opt_def_id();
|
||||
if match_def_path(cx, fun_def_id, &*paths::DISPLAY_FMT_METHOD);
|
||||
if match_def_path(cx, fun_def_id, &paths::DISPLAY_FMT_METHOD);
|
||||
then {
|
||||
let ty = walk_ptrs_ty(cx.tables.pat_ty(&pat[0]));
|
||||
if ty.sty == ty::Str || match_type(cx, ty, &*paths::STRING) {
|
||||
if ty.sty == ty::Str || match_type(cx, ty, &paths::STRING) {
|
||||
if let ExprKind::Tup(ref values) = match_expr.node {
|
||||
return Some(&values[0]);
|
||||
}
|
||||
|
@ -181,14 +180,14 @@ fn check_unformatted(expr: &Expr) -> bool {
|
|||
if let ExprKind::Array(ref exprs) = expr.node;
|
||||
if exprs.len() == 1;
|
||||
if let ExprKind::Struct(_, ref fields, _) = exprs[0].node;
|
||||
if let Some(format_field) = fields.iter().find(|f| f.ident.name == *sym::format);
|
||||
if let Some(format_field) = fields.iter().find(|f| f.ident.name == sym!(format));
|
||||
if let ExprKind::Struct(_, ref fields, _) = format_field.expr.node;
|
||||
if let Some(width_field) = fields.iter().find(|f| f.ident.name == *sym::width);
|
||||
if let Some(width_field) = fields.iter().find(|f| f.ident.name == sym!(width));
|
||||
if let ExprKind::Path(ref width_qpath) = width_field.expr.node;
|
||||
if last_path_segment(width_qpath).ident.name == *sym::Implied;
|
||||
if let Some(precision_field) = fields.iter().find(|f| f.ident.name == *sym::precision);
|
||||
if last_path_segment(width_qpath).ident.name == sym!(Implied);
|
||||
if let Some(precision_field) = fields.iter().find(|f| f.ident.name == sym!(precision));
|
||||
if let ExprKind::Path(ref precision_path) = precision_field.expr.node;
|
||||
if last_path_segment(precision_path).ident.name == *sym::Implied;
|
||||
if last_path_segment(precision_path).ident.name == sym!(Implied);
|
||||
then {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityConversion {
|
|||
},
|
||||
|
||||
ExprKind::MethodCall(ref name, .., ref args) => {
|
||||
if match_trait_method(cx, e, &*paths::INTO) && &*name.ident.as_str() == "into" {
|
||||
if match_trait_method(cx, e, &paths::INTO) && &*name.ident.as_str() == "into" {
|
||||
let a = cx.tables.expr_ty(e);
|
||||
let b = cx.tables.expr_ty(&args[0]);
|
||||
if same_tys(cx, a, b) {
|
||||
|
@ -72,7 +72,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityConversion {
|
|||
});
|
||||
}
|
||||
}
|
||||
if match_trait_method(cx, e, &*paths::INTO_ITERATOR) && &*name.ident.as_str() == "into_iter" {
|
||||
if match_trait_method(cx, e, &paths::INTO_ITERATOR) && &*name.ident.as_str() == "into_iter" {
|
||||
let a = cx.tables.expr_ty(e);
|
||||
let b = cx.tables.expr_ty(&args[0]);
|
||||
if same_tys(cx, a, b) {
|
||||
|
@ -92,7 +92,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityConversion {
|
|||
ExprKind::Call(ref path, ref args) => {
|
||||
if let ExprKind::Path(ref qpath) = path.node {
|
||||
if let Some(def_id) = resolve_node(cx, qpath, path.hir_id).opt_def_id() {
|
||||
if match_def_path(cx, def_id, &*paths::FROM_FROM) {
|
||||
if match_def_path(cx, def_id, &paths::FROM_FROM) {
|
||||
let a = cx.tables.expr_ty(e);
|
||||
let b = cx.tables.expr_ty(&args[0]);
|
||||
if same_tys(cx, a, b) {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::utils::sym;
|
||||
use crate::utils::{in_macro_or_desugar, is_expn_of, snippet_opt, span_lint_and_then};
|
||||
use rustc::hir::{intravisit::FnKind, Body, ExprKind, FnDecl, HirId, MatchSource};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
|
@ -96,7 +95,7 @@ impl ImplicitReturn {
|
|||
// everything else is missing `return`
|
||||
_ => {
|
||||
// make sure it's not just an unreachable expression
|
||||
if is_expn_of(expr.span, *sym::unreachable).is_none() {
|
||||
if is_expn_of(expr.span, "unreachable").is_none() {
|
||||
Self::lint(cx, expr.span, expr.span, "add `return` as shown")
|
||||
}
|
||||
},
|
||||
|
|
|
@ -2,10 +2,7 @@ use rustc::hir::*;
|
|||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{get_trait_def_id, higher, implements_trait, match_qpath, match_type, paths, span_lint};
|
||||
use lazy_static::lazy_static;
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for iteration that is guaranteed to be infinite.
|
||||
|
@ -112,40 +109,38 @@ enum Heuristic {
|
|||
|
||||
use self::Heuristic::{All, Always, Any, First};
|
||||
|
||||
lazy_static! {
|
||||
/// a slice of (method name, number of args, heuristic, bounds) tuples
|
||||
/// that will be used to determine whether the method in question
|
||||
/// returns an infinite or possibly infinite iterator. The finiteness
|
||||
/// is an upper bound, e.g., some methods can return a possibly
|
||||
/// infinite iterator at worst, e.g., `take_while`.
|
||||
static ref HEURISTICS: [(Symbol, usize, Heuristic, Finiteness); 19] = [
|
||||
(*sym::zip, 2, All, Infinite),
|
||||
(*sym::chain, 2, Any, Infinite),
|
||||
(*sym::cycle, 1, Always, Infinite),
|
||||
(*sym::map, 2, First, Infinite),
|
||||
(*sym::by_ref, 1, First, Infinite),
|
||||
(*sym::cloned, 1, First, Infinite),
|
||||
(*sym::rev, 1, First, Infinite),
|
||||
(*sym::inspect, 1, First, Infinite),
|
||||
(*sym::enumerate, 1, First, Infinite),
|
||||
(*sym::peekable, 2, First, Infinite),
|
||||
(*sym::fuse, 1, First, Infinite),
|
||||
(*sym::skip, 2, First, Infinite),
|
||||
(*sym::skip_while, 1, First, Infinite),
|
||||
(*sym::filter, 2, First, Infinite),
|
||||
(*sym::filter_map, 2, First, Infinite),
|
||||
(*sym::flat_map, 2, First, Infinite),
|
||||
(*sym::unzip, 1, First, Infinite),
|
||||
(*sym::take_while, 2, First, MaybeInfinite),
|
||||
(*sym::scan, 3, First, MaybeInfinite),
|
||||
const HEURISTICS: [(&str, usize, Heuristic, Finiteness); 19] = [
|
||||
("zip", 2, All, Infinite),
|
||||
("chain", 2, Any, Infinite),
|
||||
("cycle", 1, Always, Infinite),
|
||||
("map", 2, First, Infinite),
|
||||
("by_ref", 1, First, Infinite),
|
||||
("cloned", 1, First, Infinite),
|
||||
("rev", 1, First, Infinite),
|
||||
("inspect", 1, First, Infinite),
|
||||
("enumerate", 1, First, Infinite),
|
||||
("peekable", 2, First, Infinite),
|
||||
("fuse", 1, First, Infinite),
|
||||
("skip", 2, First, Infinite),
|
||||
("skip_while", 1, First, Infinite),
|
||||
("filter", 2, First, Infinite),
|
||||
("filter_map", 2, First, Infinite),
|
||||
("flat_map", 2, First, Infinite),
|
||||
("unzip", 1, First, Infinite),
|
||||
("take_while", 2, First, MaybeInfinite),
|
||||
("scan", 3, First, MaybeInfinite),
|
||||
];
|
||||
}
|
||||
|
||||
fn is_infinite(cx: &LateContext<'_, '_>, expr: &Expr) -> Finiteness {
|
||||
match expr.node {
|
||||
ExprKind::MethodCall(ref method, _, ref args) => {
|
||||
for &(name, len, heuristic, cap) in HEURISTICS.iter() {
|
||||
if method.ident.name == name && args.len() == len {
|
||||
if method.ident.name.as_str() == name && args.len() == len {
|
||||
return (match heuristic {
|
||||
Always => Infinite,
|
||||
First => is_infinite(cx, &args[0]),
|
||||
|
@ -155,7 +150,7 @@ fn is_infinite(cx: &LateContext<'_, '_>, expr: &Expr) -> Finiteness {
|
|||
.and(cap);
|
||||
}
|
||||
}
|
||||
if method.ident.name == *sym::flat_map && args.len() == 2 {
|
||||
if method.ident.name == sym!(flat_map) && args.len() == 2 {
|
||||
if let ExprKind::Closure(_, _, body_id, _, _) = args[1].node {
|
||||
let body = cx.tcx.hir().body(body_id);
|
||||
return is_infinite(cx, &body.value);
|
||||
|
@ -167,7 +162,7 @@ fn is_infinite(cx: &LateContext<'_, '_>, expr: &Expr) -> Finiteness {
|
|||
ExprKind::Box(ref e) | ExprKind::AddrOf(_, ref e) => is_infinite(cx, e),
|
||||
ExprKind::Call(ref path, _) => {
|
||||
if let ExprKind::Path(ref qpath) = path.node {
|
||||
match_qpath(qpath, &*paths::REPEAT).into()
|
||||
match_qpath(qpath, &paths::REPEAT).into()
|
||||
} else {
|
||||
Finite
|
||||
}
|
||||
|
@ -177,68 +172,66 @@ fn is_infinite(cx: &LateContext<'_, '_>, expr: &Expr) -> Finiteness {
|
|||
}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
/// the names and argument lengths of methods that *may* exhaust their
|
||||
/// iterators
|
||||
static ref POSSIBLY_COMPLETING_METHODS: [(Symbol, usize); 6] = [
|
||||
(*sym::find, 2),
|
||||
(*sym::rfind, 2),
|
||||
(*sym::position, 2),
|
||||
(*sym::rposition, 2),
|
||||
(*sym::any, 2),
|
||||
(*sym::all, 2),
|
||||
const POSSIBLY_COMPLETING_METHODS: [(&str, usize); 6] = [
|
||||
("find", 2),
|
||||
("rfind", 2),
|
||||
("position", 2),
|
||||
("rposition", 2),
|
||||
("any", 2),
|
||||
("all", 2),
|
||||
];
|
||||
|
||||
/// the names and argument lengths of methods that *always* exhaust
|
||||
/// their iterators
|
||||
static ref COMPLETING_METHODS: [(Symbol, usize); 12] = [
|
||||
(*sym::count, 1),
|
||||
(*sym::fold, 3),
|
||||
(*sym::for_each, 2),
|
||||
(*sym::partition, 2),
|
||||
(*sym::max, 1),
|
||||
(*sym::max_by, 2),
|
||||
(*sym::max_by_key, 2),
|
||||
(*sym::min, 1),
|
||||
(*sym::min_by, 2),
|
||||
(*sym::min_by_key, 2),
|
||||
(*sym::sum, 1),
|
||||
(*sym::product, 1),
|
||||
const COMPLETING_METHODS: [(&str, usize); 12] = [
|
||||
("count", 1),
|
||||
("fold", 3),
|
||||
("for_each", 2),
|
||||
("partition", 2),
|
||||
("max", 1),
|
||||
("max_by", 2),
|
||||
("max_by_key", 2),
|
||||
("min", 1),
|
||||
("min_by", 2),
|
||||
("min_by_key", 2),
|
||||
("sum", 1),
|
||||
("product", 1),
|
||||
];
|
||||
|
||||
/// the paths of types that are known to be infinitely allocating
|
||||
static ref INFINITE_COLLECTORS: [Vec<Symbol>; 8] = [
|
||||
paths::BINARY_HEAP.to_vec(),
|
||||
paths::BTREEMAP.to_vec(),
|
||||
paths::BTREESET.to_vec(),
|
||||
paths::HASHMAP.to_vec(),
|
||||
paths::HASHSET.to_vec(),
|
||||
paths::LINKED_LIST.to_vec(),
|
||||
paths::VEC.to_vec(),
|
||||
paths::VEC_DEQUE.to_vec(),
|
||||
const INFINITE_COLLECTORS: [&[&str]; 8] = [
|
||||
&paths::BINARY_HEAP,
|
||||
&paths::BTREEMAP,
|
||||
&paths::BTREESET,
|
||||
&paths::HASHMAP,
|
||||
&paths::HASHSET,
|
||||
&paths::LINKED_LIST,
|
||||
&paths::VEC,
|
||||
&paths::VEC_DEQUE,
|
||||
];
|
||||
}
|
||||
|
||||
fn complete_infinite_iter(cx: &LateContext<'_, '_>, expr: &Expr) -> Finiteness {
|
||||
match expr.node {
|
||||
ExprKind::MethodCall(ref method, _, ref args) => {
|
||||
for &(name, len) in COMPLETING_METHODS.iter() {
|
||||
if method.ident.name == name && args.len() == len {
|
||||
if method.ident.name.as_str() == name && args.len() == len {
|
||||
return is_infinite(cx, &args[0]);
|
||||
}
|
||||
}
|
||||
for &(name, len) in POSSIBLY_COMPLETING_METHODS.iter() {
|
||||
if method.ident.name == name && args.len() == len {
|
||||
if method.ident.name.as_str() == name && args.len() == len {
|
||||
return MaybeInfinite.and(is_infinite(cx, &args[0]));
|
||||
}
|
||||
}
|
||||
if method.ident.name == *sym::last && args.len() == 1 {
|
||||
let not_double_ended = get_trait_def_id(cx, &*paths::DOUBLE_ENDED_ITERATOR)
|
||||
if method.ident.name == sym!(last) && args.len() == 1 {
|
||||
let not_double_ended = get_trait_def_id(cx, &paths::DOUBLE_ENDED_ITERATOR)
|
||||
.map_or(false, |id| !implements_trait(cx, cx.tables.expr_ty(&args[0]), id, &[]));
|
||||
if not_double_ended {
|
||||
return is_infinite(cx, &args[0]);
|
||||
}
|
||||
} else if method.ident.name == *sym::collect {
|
||||
} else if method.ident.name == sym!(collect) {
|
||||
let ty = cx.tables.expr_ty(expr);
|
||||
if INFINITE_COLLECTORS.iter().any(|path| match_type(cx, ty, path)) {
|
||||
return is_infinite(cx, &args[0]);
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
use crate::utils::span_lint_and_then;
|
||||
use crate::utils::sugg::DiagnosticBuilderExt;
|
||||
use crate::utils::sym;
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_lint_pass, declare_tool_lint};
|
||||
|
@ -41,7 +40,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InlineFnWithoutBody {
|
|||
|
||||
fn check_attrs(cx: &LateContext<'_, '_>, name: Name, attrs: &[Attribute]) {
|
||||
for attr in attrs {
|
||||
if !attr.check_name(*sym::inline) {
|
||||
if !attr.check_name(sym!(inline)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,12 +37,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidRef {
|
|||
if let ty::Ref(..) = cx.tables.expr_ty(expr).sty;
|
||||
if let Some(def_id) = cx.tables.qpath_res(qpath, path.hir_id).opt_def_id();
|
||||
then {
|
||||
let msg = if match_def_path(cx, def_id, &*paths::MEM_ZEROED) |
|
||||
match_def_path(cx, def_id, &*paths::INIT)
|
||||
let msg = if match_def_path(cx, def_id, &paths::MEM_ZEROED) |
|
||||
match_def_path(cx, def_id, &paths::INIT)
|
||||
{
|
||||
ZERO_REF_SUMMARY
|
||||
} else if match_def_path(cx, def_id, &*paths::MEM_UNINIT) |
|
||||
match_def_path(cx, def_id, &*paths::UNINIT)
|
||||
} else if match_def_path(cx, def_id, &paths::MEM_UNINIT) |
|
||||
match_def_path(cx, def_id, &paths::UNINIT)
|
||||
{
|
||||
UNINIT_REF_SUMMARY
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::utils::sym;
|
||||
use crate::utils::{
|
||||
get_item_name, in_macro_or_desugar, snippet_with_applicability, span_lint, span_lint_and_sugg, walk_ptrs_ty,
|
||||
};
|
||||
|
@ -11,7 +10,6 @@ use rustc_data_structures::fx::FxHashSet;
|
|||
use rustc_errors::Applicability;
|
||||
use syntax::ast::{LitKind, Name};
|
||||
use syntax::source_map::{Span, Spanned};
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for getting the length of something via `.len()`
|
||||
|
@ -120,8 +118,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LenZero {
|
|||
}
|
||||
|
||||
fn check_trait_items(cx: &LateContext<'_, '_>, visited_trait: &Item, trait_items: &[TraitItemRef]) {
|
||||
fn is_named_self(cx: &LateContext<'_, '_>, item: &TraitItemRef, name: Symbol) -> bool {
|
||||
item.ident.name == name
|
||||
fn is_named_self(cx: &LateContext<'_, '_>, item: &TraitItemRef, name: &str) -> bool {
|
||||
item.ident.name.as_str() == name
|
||||
&& if let AssociatedItemKind::Method { has_self } = item.kind {
|
||||
has_self && {
|
||||
let did = cx.tcx.hir().local_def_id_from_hir_id(item.id.hir_id);
|
||||
|
@ -141,7 +139,7 @@ fn check_trait_items(cx: &LateContext<'_, '_>, visited_trait: &Item, trait_items
|
|||
}
|
||||
}
|
||||
|
||||
if cx.access_levels.is_exported(visited_trait.hir_id) && trait_items.iter().any(|i| is_named_self(cx, i, *sym::len))
|
||||
if cx.access_levels.is_exported(visited_trait.hir_id) && trait_items.iter().any(|i| is_named_self(cx, i, "len"))
|
||||
{
|
||||
let mut current_and_super_traits = FxHashSet::default();
|
||||
let visited_trait_def_id = cx.tcx.hir().local_def_id_from_hir_id(visited_trait.hir_id);
|
||||
|
@ -153,7 +151,7 @@ fn check_trait_items(cx: &LateContext<'_, '_>, visited_trait: &Item, trait_items
|
|||
.any(|i| {
|
||||
i.kind == ty::AssociatedKind::Method
|
||||
&& i.method_has_self_argument
|
||||
&& i.ident.name == *sym::is_empty
|
||||
&& i.ident.name == sym!(is_empty)
|
||||
&& cx.tcx.fn_sig(i.def_id).inputs().skip_binder().len() == 1
|
||||
});
|
||||
|
||||
|
@ -172,8 +170,8 @@ fn check_trait_items(cx: &LateContext<'_, '_>, visited_trait: &Item, trait_items
|
|||
}
|
||||
|
||||
fn check_impl_items(cx: &LateContext<'_, '_>, item: &Item, impl_items: &[ImplItemRef]) {
|
||||
fn is_named_self(cx: &LateContext<'_, '_>, item: &ImplItemRef, name: Symbol) -> bool {
|
||||
item.ident.name == name
|
||||
fn is_named_self(cx: &LateContext<'_, '_>, item: &ImplItemRef, name: &str) -> bool {
|
||||
item.ident.name.as_str() == name
|
||||
&& if let AssociatedItemKind::Method { has_self } = item.kind {
|
||||
has_self && {
|
||||
let did = cx.tcx.hir().local_def_id_from_hir_id(item.id.hir_id);
|
||||
|
@ -184,7 +182,7 @@ fn check_impl_items(cx: &LateContext<'_, '_>, item: &Item, impl_items: &[ImplIte
|
|||
}
|
||||
}
|
||||
|
||||
let is_empty = if let Some(is_empty) = impl_items.iter().find(|i| is_named_self(cx, i, *sym::is_empty)) {
|
||||
let is_empty = if let Some(is_empty) = impl_items.iter().find(|i| is_named_self(cx, i, "is_empty")) {
|
||||
if cx.access_levels.is_exported(is_empty.id.hir_id) {
|
||||
return;
|
||||
} else {
|
||||
|
@ -194,7 +192,7 @@ fn check_impl_items(cx: &LateContext<'_, '_>, item: &Item, impl_items: &[ImplIte
|
|||
"no corresponding"
|
||||
};
|
||||
|
||||
if let Some(i) = impl_items.iter().find(|i| is_named_self(cx, i, *sym::len)) {
|
||||
if let Some(i) = impl_items.iter().find(|i| is_named_self(cx, i, "len")) {
|
||||
if cx.access_levels.is_exported(i.id.hir_id) {
|
||||
let def_id = cx.tcx.hir().local_def_id_from_hir_id(item.hir_id);
|
||||
let ty = cx.tcx.type_of(def_id);
|
||||
|
@ -216,7 +214,7 @@ fn check_cmp(cx: &LateContext<'_, '_>, span: Span, method: &Expr, lit: &Expr, op
|
|||
if let (&ExprKind::MethodCall(ref method_path, _, ref args), &ExprKind::Lit(ref lit)) = (&method.node, &lit.node) {
|
||||
// check if we are in an is_empty() method
|
||||
if let Some(name) = get_item_name(cx, method) {
|
||||
if name == *sym::is_empty {
|
||||
if name.as_str() == "is_empty" {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -240,7 +238,7 @@ fn check_len(
|
|||
return;
|
||||
}
|
||||
|
||||
if method_name == *sym::len && args.len() == 1 && has_is_empty(cx, &args[0]) {
|
||||
if method_name.as_str() == "len" && args.len() == 1 && has_is_empty(cx, &args[0]) {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
|
@ -264,7 +262,7 @@ fn has_is_empty(cx: &LateContext<'_, '_>, expr: &Expr) -> bool {
|
|||
/// Gets an `AssociatedItem` and return true if it matches `is_empty(self)`.
|
||||
fn is_is_empty(cx: &LateContext<'_, '_>, item: &ty::AssociatedItem) -> bool {
|
||||
if let ty::AssociatedKind::Method = item.kind {
|
||||
if item.ident.name == *sym::is_empty {
|
||||
if item.ident.name.as_str() == "is_empty" {
|
||||
let sig = cx.tcx.fn_sig(item.def_id);
|
||||
let ty = sig.skip_binder();
|
||||
ty.inputs().len() == 1
|
||||
|
|
|
@ -10,7 +10,6 @@ use rustc::middle::region;
|
|||
use rustc::{declare_lint_pass, declare_tool_lint};
|
||||
// use rustc::middle::region::CodeExtent;
|
||||
use crate::consts::{constant, Constant};
|
||||
use crate::utils::sym;
|
||||
use crate::utils::usage::mutated_variables;
|
||||
use crate::utils::{in_macro_or_desugar, sext, sugg};
|
||||
use rustc::middle::expr_use_visitor::*;
|
||||
|
@ -555,9 +554,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Loops {
|
|||
{
|
||||
let iter_expr = &method_args[0];
|
||||
let lhs_constructor = last_path_segment(qpath);
|
||||
if method_path.ident.name == *sym::next
|
||||
&& match_trait_method(cx, match_expr, &*paths::ITERATOR)
|
||||
&& lhs_constructor.ident.name == *sym::Some
|
||||
if method_path.ident.name == sym!(next)
|
||||
&& match_trait_method(cx, match_expr, &paths::ITERATOR)
|
||||
&& lhs_constructor.ident.name == sym!(Some)
|
||||
&& (pat_args.is_empty()
|
||||
|| !is_refutable(cx, &pat_args[0])
|
||||
&& !is_used_inside(cx, iter_expr, &arms[0].body)
|
||||
|
@ -595,8 +594,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Loops {
|
|||
if let StmtKind::Semi(ref expr) = stmt.node {
|
||||
if let ExprKind::MethodCall(ref method, _, ref args) = expr.node {
|
||||
if args.len() == 1
|
||||
&& method.ident.name == *sym::collect
|
||||
&& match_trait_method(cx, expr, &*paths::ITERATOR)
|
||||
&& method.ident.name == sym!(collect)
|
||||
&& match_trait_method(cx, expr, &paths::ITERATOR)
|
||||
{
|
||||
span_lint(
|
||||
cx,
|
||||
|
@ -815,7 +814,7 @@ fn is_slice_like<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'_>) -> bool {
|
|||
_ => false,
|
||||
};
|
||||
|
||||
is_slice || match_type(cx, ty, &*paths::VEC) || match_type(cx, ty, &*paths::VEC_DEQUE)
|
||||
is_slice || match_type(cx, ty, &paths::VEC) || match_type(cx, ty, &paths::VEC_DEQUE)
|
||||
}
|
||||
|
||||
fn get_fixed_offset_var<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr, var: HirId) -> Option<FixedOffsetVar> {
|
||||
|
@ -878,7 +877,7 @@ fn fetch_cloned_fixed_offset_var<'a, 'tcx>(
|
|||
) -> Option<FixedOffsetVar> {
|
||||
if_chain! {
|
||||
if let ExprKind::MethodCall(ref method, _, ref args) = expr.node;
|
||||
if method.ident.name == *sym::clone;
|
||||
if method.ident.name == sym!(clone);
|
||||
if args.len() == 1;
|
||||
if let Some(arg) = args.get(0);
|
||||
then {
|
||||
|
@ -984,7 +983,7 @@ fn detect_manual_memcpy<'a, 'tcx>(
|
|||
if let Some(end) = *end {
|
||||
if_chain! {
|
||||
if let ExprKind::MethodCall(ref method, _, ref len_args) = end.node;
|
||||
if method.ident.name == *sym::len;
|
||||
if method.ident.name == sym!(len);
|
||||
if len_args.len() == 1;
|
||||
if let Some(arg) = len_args.get(0);
|
||||
if snippet(cx, arg.span, "??") == var_name;
|
||||
|
@ -1226,7 +1225,7 @@ fn is_len_call(expr: &Expr, var: Name) -> bool {
|
|||
if_chain! {
|
||||
if let ExprKind::MethodCall(ref method, _, ref len_args) = expr.node;
|
||||
if len_args.len() == 1;
|
||||
if method.ident.name == *sym::len;
|
||||
if method.ident.name == sym!(len);
|
||||
if let ExprKind::Path(QPath::Resolved(_, ref path)) = len_args[0].node;
|
||||
if path.segments.len() == 1;
|
||||
if path.segments[0].ident.name == var;
|
||||
|
@ -1354,7 +1353,7 @@ fn check_for_loop_arg(cx: &LateContext<'_, '_>, pat: &Pat, arg: &Expr, expr: &Ex
|
|||
if is_ref_iterable_type(cx, &args[0]) {
|
||||
lint_iter_method(cx, args, arg, method_name);
|
||||
}
|
||||
} else if method_name == "into_iter" && match_trait_method(cx, arg, &*paths::INTO_ITERATOR) {
|
||||
} else if method_name == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) {
|
||||
let def_id = cx.tables.type_dependent_def_id(arg.hir_id).unwrap();
|
||||
let substs = cx.tables.node_substs(arg.hir_id);
|
||||
let method_type = cx.tcx.type_of(def_id).subst(cx.tcx, substs);
|
||||
|
@ -1382,7 +1381,7 @@ fn check_for_loop_arg(cx: &LateContext<'_, '_>, pat: &Pat, arg: &Expr, expr: &Ex
|
|||
applicability,
|
||||
);
|
||||
}
|
||||
} else if method_name == "next" && match_trait_method(cx, arg, &*paths::ITERATOR) {
|
||||
} else if method_name == "next" && match_trait_method(cx, arg, &paths::ITERATOR) {
|
||||
span_lint(
|
||||
cx,
|
||||
ITER_NEXT_LOOP,
|
||||
|
@ -1402,7 +1401,7 @@ fn check_for_loop_arg(cx: &LateContext<'_, '_>, pat: &Pat, arg: &Expr, expr: &Ex
|
|||
/// Checks for `for` loops over `Option`s and `Result`s.
|
||||
fn check_arg_type(cx: &LateContext<'_, '_>, pat: &Pat, arg: &Expr) {
|
||||
let ty = cx.tables.expr_ty(arg);
|
||||
if match_type(cx, ty, &*paths::OPTION) {
|
||||
if match_type(cx, ty, &paths::OPTION) {
|
||||
span_help_and_lint(
|
||||
cx,
|
||||
FOR_LOOP_OVER_OPTION,
|
||||
|
@ -1418,7 +1417,7 @@ fn check_arg_type(cx: &LateContext<'_, '_>, pat: &Pat, arg: &Expr) {
|
|||
snippet(cx, arg.span, "_")
|
||||
),
|
||||
);
|
||||
} else if match_type(cx, ty, &*paths::RESULT) {
|
||||
} else if match_type(cx, ty, &paths::RESULT) {
|
||||
span_help_and_lint(
|
||||
cx,
|
||||
FOR_LOOP_OVER_RESULT,
|
||||
|
@ -1531,7 +1530,7 @@ fn check_for_loop_over_map_kv<'a, 'tcx>(
|
|||
_ => arg,
|
||||
};
|
||||
|
||||
if match_type(cx, ty, &*paths::HASHMAP) || match_type(cx, ty, &*paths::BTREEMAP) {
|
||||
if match_type(cx, ty, &paths::HASHMAP) || match_type(cx, ty, &paths::BTREEMAP) {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
FOR_KV_MAP,
|
||||
|
@ -1811,8 +1810,8 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
|
|||
if_chain! {
|
||||
// a range index op
|
||||
if let ExprKind::MethodCall(ref meth, _, ref args) = expr.node;
|
||||
if (meth.ident.name == *sym::index && match_trait_method(self.cx, expr, &*paths::INDEX))
|
||||
|| (meth.ident.name == *sym::index_mut && match_trait_method(self.cx, expr, &*paths::INDEX_MUT));
|
||||
if (meth.ident.name == sym!(index) && match_trait_method(self.cx, expr, &paths::INDEX))
|
||||
|| (meth.ident.name == sym!(index_mut) && match_trait_method(self.cx, expr, &paths::INDEX_MUT));
|
||||
if !self.check(&args[1], &args[0], expr);
|
||||
then { return }
|
||||
}
|
||||
|
@ -1967,14 +1966,14 @@ fn is_ref_iterable_type(cx: &LateContext<'_, '_>, e: &Expr) -> bool {
|
|||
// will allow further borrows afterwards
|
||||
let ty = cx.tables.expr_ty(e);
|
||||
is_iterable_array(ty, cx) ||
|
||||
match_type(cx, ty, &*paths::VEC) ||
|
||||
match_type(cx, ty, &*paths::LINKED_LIST) ||
|
||||
match_type(cx, ty, &*paths::HASHMAP) ||
|
||||
match_type(cx, ty, &*paths::HASHSET) ||
|
||||
match_type(cx, ty, &*paths::VEC_DEQUE) ||
|
||||
match_type(cx, ty, &*paths::BINARY_HEAP) ||
|
||||
match_type(cx, ty, &*paths::BTREEMAP) ||
|
||||
match_type(cx, ty, &*paths::BTREESET)
|
||||
match_type(cx, ty, &paths::VEC) ||
|
||||
match_type(cx, ty, &paths::LINKED_LIST) ||
|
||||
match_type(cx, ty, &paths::HASHMAP) ||
|
||||
match_type(cx, ty, &paths::HASHSET) ||
|
||||
match_type(cx, ty, &paths::VEC_DEQUE) ||
|
||||
match_type(cx, ty, &paths::BINARY_HEAP) ||
|
||||
match_type(cx, ty, &paths::BTREEMAP) ||
|
||||
match_type(cx, ty, &paths::BTREESET)
|
||||
}
|
||||
|
||||
fn is_iterable_array(ty: Ty<'_>, cx: &LateContext<'_, '_>) -> bool {
|
||||
|
@ -2415,16 +2414,16 @@ fn check_needless_collect<'a, 'tcx>(expr: &'tcx Expr, cx: &LateContext<'a, 'tcx>
|
|||
if_chain! {
|
||||
if let ExprKind::MethodCall(ref method, _, ref args) = expr.node;
|
||||
if let ExprKind::MethodCall(ref chain_method, _, _) = args[0].node;
|
||||
if chain_method.ident.name == *sym::collect && match_trait_method(cx, &args[0], &*paths::ITERATOR);
|
||||
if chain_method.ident.name == sym!(collect) && match_trait_method(cx, &args[0], &paths::ITERATOR);
|
||||
if let Some(ref generic_args) = chain_method.args;
|
||||
if let Some(GenericArg::Type(ref ty)) = generic_args.args.get(0);
|
||||
then {
|
||||
let ty = cx.tables.node_type(ty.hir_id);
|
||||
if match_type(cx, ty, &*paths::VEC) ||
|
||||
match_type(cx, ty, &*paths::VEC_DEQUE) ||
|
||||
match_type(cx, ty, &*paths::BTREEMAP) ||
|
||||
match_type(cx, ty, &*paths::HASHMAP) {
|
||||
if method.ident.name == *sym::len {
|
||||
if match_type(cx, ty, &paths::VEC) ||
|
||||
match_type(cx, ty, &paths::VEC_DEQUE) ||
|
||||
match_type(cx, ty, &paths::BTREEMAP) ||
|
||||
match_type(cx, ty, &paths::HASHMAP) {
|
||||
if method.ident.name == sym!(len) {
|
||||
let span = shorten_needless_collect_span(expr);
|
||||
span_lint_and_then(cx, NEEDLESS_COLLECT, span, NEEDLESS_COLLECT_MSG, |db| {
|
||||
db.span_suggestion(
|
||||
|
@ -2435,7 +2434,7 @@ fn check_needless_collect<'a, 'tcx>(expr: &'tcx Expr, cx: &LateContext<'a, 'tcx>
|
|||
);
|
||||
});
|
||||
}
|
||||
if method.ident.name == *sym::is_empty {
|
||||
if method.ident.name == sym!(is_empty) {
|
||||
let span = shorten_needless_collect_span(expr);
|
||||
span_lint_and_then(cx, NEEDLESS_COLLECT, span, NEEDLESS_COLLECT_MSG, |db| {
|
||||
db.span_suggestion(
|
||||
|
@ -2446,7 +2445,7 @@ fn check_needless_collect<'a, 'tcx>(expr: &'tcx Expr, cx: &LateContext<'a, 'tcx>
|
|||
);
|
||||
});
|
||||
}
|
||||
if method.ident.name == *sym::contains {
|
||||
if method.ident.name == sym!(contains) {
|
||||
let contains_arg = snippet(cx, args[1].span, "??");
|
||||
let span = shorten_needless_collect_span(expr);
|
||||
span_lint_and_then(cx, NEEDLESS_COLLECT, span, NEEDLESS_COLLECT_MSG, |db| {
|
||||
|
|
|
@ -53,7 +53,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MapClone {
|
|||
if args.len() == 2;
|
||||
if method.ident.as_str() == "map";
|
||||
let ty = cx.tables.expr_ty(&args[0]);
|
||||
if match_type(cx, ty, &*paths::OPTION) || match_trait_method(cx, e, &*paths::ITERATOR);
|
||||
if match_type(cx, ty, &paths::OPTION) || match_trait_method(cx, e, &paths::ITERATOR);
|
||||
if let hir::ExprKind::Closure(_, _, body_id, _, _) = args[1].node;
|
||||
let closure_body = cx.tcx.hir().body(body_id);
|
||||
let closure_expr = remove_blocks(&closure_body.value);
|
||||
|
@ -75,7 +75,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MapClone {
|
|||
},
|
||||
hir::ExprKind::MethodCall(ref method, _, ref obj) => {
|
||||
if ident_eq(name, &obj[0]) && method.ident.as_str() == "clone"
|
||||
&& match_trait_method(cx, closure_expr, &*paths::CLONE_TRAIT) {
|
||||
&& match_trait_method(cx, closure_expr, &paths::CLONE_TRAIT) {
|
||||
|
||||
let obj_ty = cx.tables.expr_ty(&obj[0]);
|
||||
if let ty::Ref(_, ty, _) = obj_ty.sty {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use crate::utils::paths;
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{in_macro_or_desugar, iter_input_pats, match_type, method_chain_args, snippet, span_lint_and_then};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir;
|
||||
|
@ -186,9 +185,9 @@ fn suggestion_msg(function_type: &str, map_type: &str) -> String {
|
|||
fn lint_map_unit_fn(cx: &LateContext<'_, '_>, stmt: &hir::Stmt, expr: &hir::Expr, map_args: &[hir::Expr]) {
|
||||
let var_arg = &map_args[0];
|
||||
|
||||
let (map_type, variant, lint) = if match_type(cx, cx.tables.expr_ty(var_arg), &*paths::OPTION) {
|
||||
let (map_type, variant, lint) = if match_type(cx, cx.tables.expr_ty(var_arg), &paths::OPTION) {
|
||||
("Option", "Some", OPTION_MAP_UNIT_FN)
|
||||
} else if match_type(cx, cx.tables.expr_ty(var_arg), &*paths::RESULT) {
|
||||
} else if match_type(cx, cx.tables.expr_ty(var_arg), &paths::RESULT) {
|
||||
("Result", "Ok", RESULT_MAP_UNIT_FN)
|
||||
} else {
|
||||
return;
|
||||
|
@ -246,7 +245,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MapUnit {
|
|||
}
|
||||
|
||||
if let hir::StmtKind::Semi(ref expr) = stmt.node {
|
||||
if let Some(arglists) = method_chain_args(expr, &[*sym::map]) {
|
||||
if let Some(arglists) = method_chain_args(expr, &["map"]) {
|
||||
lint_map_unit_fn(cx, stmt, expr, arglists[0]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use crate::consts::{constant, Constant};
|
||||
use crate::utils::paths;
|
||||
use crate::utils::sugg::Sugg;
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{
|
||||
expr_block, in_macro_or_desugar, is_allowed, is_expn_of, match_qpath, match_type, multispan_sugg, remove_blocks,
|
||||
snippet, snippet_with_applicability, span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty,
|
||||
|
@ -320,13 +319,13 @@ fn check_single_match_opt_like(
|
|||
) {
|
||||
// list of candidate `Enum`s we know will never get any more members
|
||||
let candidates = &[
|
||||
(&*paths::COW, "Borrowed"),
|
||||
(&*paths::COW, "Cow::Borrowed"),
|
||||
(&*paths::COW, "Cow::Owned"),
|
||||
(&*paths::COW, "Owned"),
|
||||
(&*paths::OPTION, "None"),
|
||||
(&*paths::RESULT, "Err"),
|
||||
(&*paths::RESULT, "Ok"),
|
||||
(&paths::COW, "Borrowed"),
|
||||
(&paths::COW, "Cow::Borrowed"),
|
||||
(&paths::COW, "Cow::Owned"),
|
||||
(&paths::COW, "Owned"),
|
||||
(&paths::OPTION, "None"),
|
||||
(&paths::RESULT, "Err"),
|
||||
(&paths::RESULT, "Ok"),
|
||||
];
|
||||
|
||||
let path = match arms[1].pats[0].node {
|
||||
|
@ -437,7 +436,7 @@ fn is_wild(pat: &impl std::ops::Deref<Target = Pat>) -> bool {
|
|||
|
||||
fn check_wild_err_arm(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) {
|
||||
let ex_ty = walk_ptrs_ty(cx.tables.expr_ty(ex));
|
||||
if match_type(cx, ex_ty, &*paths::RESULT) {
|
||||
if match_type(cx, ex_ty, &paths::RESULT) {
|
||||
for arm in arms {
|
||||
if let PatKind::TupleStruct(ref path, ref inner, _) = arm.pats[0].node {
|
||||
let path_str = print::to_string(print::NO_ANN, |s| s.print_qpath(path, false));
|
||||
|
@ -553,10 +552,10 @@ fn check_wild_enum_match(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) {
|
|||
fn is_panic_block(block: &Block) -> bool {
|
||||
match (&block.expr, block.stmts.len(), block.stmts.first()) {
|
||||
(&Some(ref exp), 0, _) => {
|
||||
is_expn_of(exp.span, *sym::panic).is_some() && is_expn_of(exp.span, *sym::unreachable).is_none()
|
||||
is_expn_of(exp.span, "panic").is_some() && is_expn_of(exp.span, "unreachable").is_none()
|
||||
},
|
||||
(&None, 1, Some(stmt)) => {
|
||||
is_expn_of(stmt.span, *sym::panic).is_some() && is_expn_of(stmt.span, *sym::unreachable).is_none()
|
||||
is_expn_of(stmt.span, "panic").is_some() && is_expn_of(stmt.span, "unreachable").is_none()
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
|
@ -718,7 +717,7 @@ fn is_unit_expr(expr: &Expr) -> bool {
|
|||
// Checks if arm has the form `None => None`
|
||||
fn is_none_arm(arm: &Arm) -> bool {
|
||||
match arm.pats[0].node {
|
||||
PatKind::Path(ref path) if match_qpath(path, &*paths::OPTION_NONE) => true,
|
||||
PatKind::Path(ref path) if match_qpath(path, &paths::OPTION_NONE) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -727,12 +726,12 @@ fn is_none_arm(arm: &Arm) -> bool {
|
|||
fn is_ref_some_arm(arm: &Arm) -> Option<BindingAnnotation> {
|
||||
if_chain! {
|
||||
if let PatKind::TupleStruct(ref path, ref pats, _) = arm.pats[0].node;
|
||||
if pats.len() == 1 && match_qpath(path, &*paths::OPTION_SOME);
|
||||
if pats.len() == 1 && match_qpath(path, &paths::OPTION_SOME);
|
||||
if let PatKind::Binding(rb, .., ident, _) = pats[0].node;
|
||||
if rb == BindingAnnotation::Ref || rb == BindingAnnotation::RefMut;
|
||||
if let ExprKind::Call(ref e, ref args) = remove_blocks(&arm.body).node;
|
||||
if let ExprKind::Path(ref some_path) = e.node;
|
||||
if match_qpath(some_path, &*paths::OPTION_SOME) && args.len() == 1;
|
||||
if match_qpath(some_path, &paths::OPTION_SOME) && args.len() == 1;
|
||||
if let ExprKind::Path(ref qpath) = args[0].node;
|
||||
if let &QPath::Resolved(_, ref path2) = qpath;
|
||||
if path2.segments.len() == 1 && ident.name == path2.segments[0].ident.name;
|
||||
|
|
|
@ -36,7 +36,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemDiscriminant {
|
|||
// is `mem::discriminant`
|
||||
if let ExprKind::Path(ref func_qpath) = func.node;
|
||||
if let Some(def_id) = cx.tables.qpath_res(func_qpath, func.hir_id).opt_def_id();
|
||||
if match_def_path(cx, def_id, &*paths::MEM_DISCRIMINANT);
|
||||
if match_def_path(cx, def_id, &paths::MEM_DISCRIMINANT);
|
||||
// type is non-enum
|
||||
let ty_param = cx.tables.node_substs(func.hir_id).type_at(0);
|
||||
if !ty_param.is_enum();
|
||||
|
|
|
@ -28,7 +28,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemForget {
|
|||
if let ExprKind::Call(ref path_expr, ref args) = e.node {
|
||||
if let ExprKind::Path(ref qpath) = path_expr.node {
|
||||
if let Some(def_id) = cx.tables.qpath_res(qpath, path_expr.hir_id).opt_def_id() {
|
||||
if match_def_path(cx, def_id, &*paths::MEM_FORGET) {
|
||||
if match_def_path(cx, def_id, &paths::MEM_FORGET) {
|
||||
let forgot_ty = cx.tables.expr_ty(&args[0]);
|
||||
|
||||
if forgot_ty.ty_adt_def().map_or(false, |def| def.has_dtor(cx.tcx)) {
|
||||
|
|
|
@ -42,11 +42,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemReplace {
|
|||
if func_args.len() == 2;
|
||||
if let ExprKind::Path(ref func_qpath) = func.node;
|
||||
if let Some(def_id) = cx.tables.qpath_res(func_qpath, func.hir_id).opt_def_id();
|
||||
if match_def_path(cx, def_id, &*paths::MEM_REPLACE);
|
||||
if match_def_path(cx, def_id, &paths::MEM_REPLACE);
|
||||
|
||||
// Check that second argument is `Option::None`
|
||||
if let ExprKind::Path(ref replacement_qpath) = func_args[1].node;
|
||||
if match_qpath(replacement_qpath, &*paths::OPTION_NONE);
|
||||
if match_qpath(replacement_qpath, &paths::OPTION_NONE);
|
||||
|
||||
then {
|
||||
// Since this is a late pass (already type-checked),
|
||||
|
|
|
@ -21,7 +21,6 @@ use syntax::symbol::{LocalInternedString, Symbol};
|
|||
|
||||
use crate::utils::paths;
|
||||
use crate::utils::sugg;
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{
|
||||
get_arg_name, get_parent_expr, get_trait_def_id, has_iter_method, implements_trait, in_macro, is_copy,
|
||||
is_ctor_function, is_expn_of, is_self, is_self_ty, iter_input_pats, last_path_segment, match_def_path, match_path,
|
||||
|
@ -908,7 +907,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
|
|||
lint_expect_fun_call(cx, expr, *method_span, &method_call.ident.as_str(), args);
|
||||
|
||||
let self_ty = cx.tables.expr_ty_adjusted(&args[0]);
|
||||
if args.len() == 1 && method_call.ident.name == *sym::clone {
|
||||
if args.len() == 1 && method_call.ident.name == sym!(clone) {
|
||||
lint_clone_on_copy(cx, expr, &args[0], self_ty);
|
||||
lint_clone_on_ref_ptr(cx, expr, &args[0]);
|
||||
}
|
||||
|
@ -921,7 +920,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
|
|||
}
|
||||
}
|
||||
},
|
||||
ty::Ref(..) if method_call.ident.name == *sym::into_iter => {
|
||||
ty::Ref(..) if method_call.ident.name == sym!(into_iter) => {
|
||||
lint_into_iter(cx, expr, self_ty, *method_span);
|
||||
},
|
||||
_ => (),
|
||||
|
@ -1033,7 +1032,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
|
|||
}
|
||||
}
|
||||
|
||||
if name == *sym::new && !same_tys(cx, ret_ty, ty) {
|
||||
if name == sym!(new) && !same_tys(cx, ret_ty, ty) {
|
||||
span_lint(
|
||||
cx,
|
||||
NEW_RET_NO_SELF,
|
||||
|
@ -1112,7 +1111,7 @@ fn lint_or_fun_call<'a, 'tcx: 'a>(
|
|||
|
||||
if ["default", "new"].contains(&path) {
|
||||
let arg_ty = cx.tables.expr_ty(arg);
|
||||
let default_trait_id = if let Some(default_trait_id) = get_trait_def_id(cx, &*paths::DEFAULT_TRAIT)
|
||||
let default_trait_id = if let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT)
|
||||
{
|
||||
default_trait_id
|
||||
} else {
|
||||
|
@ -1156,10 +1155,10 @@ fn lint_or_fun_call<'a, 'tcx: 'a>(
|
|||
) {
|
||||
// (path, fn_has_argument, methods, suffix)
|
||||
let know_types: &[(&[_], _, &[_], _)] = &[
|
||||
(&*paths::BTREEMAP_ENTRY, false, &["or_insert"], "with"),
|
||||
(&*paths::HASHMAP_ENTRY, false, &["or_insert"], "with"),
|
||||
(&*paths::OPTION, false, &["map_or", "ok_or", "or", "unwrap_or"], "else"),
|
||||
(&*paths::RESULT, true, &["or", "unwrap_or"], "else"),
|
||||
(&paths::BTREEMAP_ENTRY, false, &["or_insert"], "with"),
|
||||
(&paths::HASHMAP_ENTRY, false, &["or_insert"], "with"),
|
||||
(&paths::OPTION, false, &["map_or", "ok_or", "or", "unwrap_or"], "else"),
|
||||
(&paths::RESULT, true, &["or", "unwrap_or"], "else"),
|
||||
];
|
||||
|
||||
// early check if the name is one we care about
|
||||
|
@ -1248,11 +1247,11 @@ fn lint_expect_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span:
|
|||
hir::ExprKind::AddrOf(_, expr) => expr,
|
||||
hir::ExprKind::MethodCall(method_name, _, call_args) => {
|
||||
if call_args.len() == 1
|
||||
&& (method_name.ident.name == *sym::as_str || method_name.ident.name == *sym::as_ref)
|
||||
&& (method_name.ident.name == sym!(as_str) || method_name.ident.name == sym!(as_ref))
|
||||
&& {
|
||||
let arg_type = cx.tables.expr_ty(&call_args[0]);
|
||||
let base_type = walk_ptrs_ty(arg_type);
|
||||
base_type.sty == ty::Str || match_type(cx, base_type, &*paths::STRING)
|
||||
base_type.sty == ty::Str || match_type(cx, base_type, &paths::STRING)
|
||||
}
|
||||
{
|
||||
&call_args[0]
|
||||
|
@ -1270,7 +1269,7 @@ fn lint_expect_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span:
|
|||
// converted to string.
|
||||
fn requires_to_string(cx: &LateContext<'_, '_>, arg: &hir::Expr) -> bool {
|
||||
let arg_ty = cx.tables.expr_ty(arg);
|
||||
if match_type(cx, arg_ty, &*paths::STRING) {
|
||||
if match_type(cx, arg_ty, &paths::STRING) {
|
||||
return false;
|
||||
}
|
||||
if let ty::Ref(ty::ReStatic, ty, ..) = arg_ty.sty {
|
||||
|
@ -1319,9 +1318,9 @@ fn lint_expect_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span:
|
|||
}
|
||||
|
||||
let receiver_type = cx.tables.expr_ty(&args[0]);
|
||||
let closure_args = if match_type(cx, receiver_type, &*paths::OPTION) {
|
||||
let closure_args = if match_type(cx, receiver_type, &paths::OPTION) {
|
||||
"||"
|
||||
} else if match_type(cx, receiver_type, &*paths::RESULT) {
|
||||
} else if match_type(cx, receiver_type, &paths::RESULT) {
|
||||
"|_|"
|
||||
} else {
|
||||
return;
|
||||
|
@ -1335,7 +1334,7 @@ fn lint_expect_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span:
|
|||
|
||||
//Special handling for `format!` as arg_root
|
||||
if let hir::ExprKind::Call(ref inner_fun, ref inner_args) = arg_root.node {
|
||||
if is_expn_of(inner_fun.span, *sym::format).is_some() && inner_args.len() == 1 {
|
||||
if is_expn_of(inner_fun.span, "format").is_some() && inner_args.len() == 1 {
|
||||
if let hir::ExprKind::Call(_, format_args) = &inner_args[0].node {
|
||||
let fmt_spec = &format_args[0];
|
||||
let fmt_args = &format_args[1];
|
||||
|
@ -1475,11 +1474,11 @@ fn lint_clone_on_ref_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr, arg: &hir::
|
|||
let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(arg));
|
||||
|
||||
if let ty::Adt(_, subst) = obj_ty.sty {
|
||||
let caller_type = if match_type(cx, obj_ty, &*paths::RC) {
|
||||
let caller_type = if match_type(cx, obj_ty, &paths::RC) {
|
||||
"Rc"
|
||||
} else if match_type(cx, obj_ty, &*paths::ARC) {
|
||||
} else if match_type(cx, obj_ty, &paths::ARC) {
|
||||
"Arc"
|
||||
} else if match_type(cx, obj_ty, &*paths::WEAK_RC) || match_type(cx, obj_ty, &*paths::WEAK_ARC) {
|
||||
} else if match_type(cx, obj_ty, &paths::WEAK_RC) || match_type(cx, obj_ty, &paths::WEAK_ARC) {
|
||||
"Weak"
|
||||
} else {
|
||||
return;
|
||||
|
@ -1504,12 +1503,12 @@ fn lint_clone_on_ref_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr, arg: &hir::
|
|||
|
||||
fn lint_string_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr, args: &[hir::Expr]) {
|
||||
let arg = &args[1];
|
||||
if let Some(arglists) = method_chain_args(arg, &[*sym::chars]) {
|
||||
if let Some(arglists) = method_chain_args(arg, &["chars"]) {
|
||||
let target = &arglists[0][0];
|
||||
let self_ty = walk_ptrs_ty(cx.tables.expr_ty(target));
|
||||
let ref_str = if self_ty.sty == ty::Str {
|
||||
""
|
||||
} else if match_type(cx, self_ty, &*paths::STRING) {
|
||||
} else if match_type(cx, self_ty, &paths::STRING) {
|
||||
"&"
|
||||
} else {
|
||||
return;
|
||||
|
@ -1535,7 +1534,7 @@ fn lint_string_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr, args: &[hir::E
|
|||
|
||||
fn lint_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr, args: &[hir::Expr]) {
|
||||
let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&args[0]));
|
||||
if match_type(cx, obj_ty, &*paths::STRING) {
|
||||
if match_type(cx, obj_ty, &paths::STRING) {
|
||||
lint_string_extend(cx, expr, args);
|
||||
}
|
||||
}
|
||||
|
@ -1546,7 +1545,7 @@ fn lint_cstring_as_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr, new: &hir::Ex
|
|||
if args.len() == 1;
|
||||
if let hir::ExprKind::Path(ref path) = fun.node;
|
||||
if let Res::Def(DefKind::Method, did) = cx.tables.qpath_res(path, fun.hir_id);
|
||||
if match_def_path(cx, did, &*paths::CSTRING_NEW);
|
||||
if match_def_path(cx, did, &paths::CSTRING_NEW);
|
||||
then {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
|
@ -1562,7 +1561,7 @@ fn lint_cstring_as_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr, new: &hir::Ex
|
|||
}
|
||||
|
||||
fn lint_iter_cloned_collect<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &hir::Expr, iter_args: &'tcx [hir::Expr]) {
|
||||
if match_type(cx, cx.tables.expr_ty(expr), &*paths::VEC) {
|
||||
if match_type(cx, cx.tables.expr_ty(expr), &paths::VEC) {
|
||||
if let Some(slice) = derefs_to_slice(cx, &iter_args[0], cx.tables.expr_ty(&iter_args[0])) {
|
||||
if let Some(to_replace) = expr.span.trim_start(slice.span.source_callsite()) {
|
||||
span_lint_and_sugg(
|
||||
|
@ -1640,7 +1639,7 @@ fn lint_unnecessary_fold(cx: &LateContext<'_, '_>, expr: &hir::Expr, fold_args:
|
|||
}
|
||||
|
||||
// Check that this is a call to Iterator::fold rather than just some function called fold
|
||||
if !match_trait_method(cx, expr, &*paths::ITERATOR) {
|
||||
if !match_trait_method(cx, expr, &paths::ITERATOR) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1666,9 +1665,9 @@ fn lint_iter_nth<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &hir::Expr, iter_ar
|
|||
let mut_str = if is_mut { "_mut" } else { "" };
|
||||
let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.tables.expr_ty(&iter_args[0])).is_some() {
|
||||
"slice"
|
||||
} else if match_type(cx, cx.tables.expr_ty(&iter_args[0]), &*paths::VEC) {
|
||||
} else if match_type(cx, cx.tables.expr_ty(&iter_args[0]), &paths::VEC) {
|
||||
"Vec"
|
||||
} else if match_type(cx, cx.tables.expr_ty(&iter_args[0]), &*paths::VEC_DEQUE) {
|
||||
} else if match_type(cx, cx.tables.expr_ty(&iter_args[0]), &paths::VEC_DEQUE) {
|
||||
"VecDeque"
|
||||
} else {
|
||||
return; // caller is not a type that we want to lint
|
||||
|
@ -1699,16 +1698,16 @@ fn lint_get_unwrap<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &hir::Expr, get_a
|
|||
let caller_type = if derefs_to_slice(cx, &get_args[0], expr_ty).is_some() {
|
||||
needs_ref = get_args_str.parse::<usize>().is_ok();
|
||||
"slice"
|
||||
} else if match_type(cx, expr_ty, &*paths::VEC) {
|
||||
} else if match_type(cx, expr_ty, &paths::VEC) {
|
||||
needs_ref = get_args_str.parse::<usize>().is_ok();
|
||||
"Vec"
|
||||
} else if match_type(cx, expr_ty, &*paths::VEC_DEQUE) {
|
||||
} else if match_type(cx, expr_ty, &paths::VEC_DEQUE) {
|
||||
needs_ref = get_args_str.parse::<usize>().is_ok();
|
||||
"VecDeque"
|
||||
} else if !is_mut && match_type(cx, expr_ty, &*paths::HASHMAP) {
|
||||
} else if !is_mut && match_type(cx, expr_ty, &paths::HASHMAP) {
|
||||
needs_ref = true;
|
||||
"HashMap"
|
||||
} else if !is_mut && match_type(cx, expr_ty, &*paths::BTREEMAP) {
|
||||
} else if !is_mut && match_type(cx, expr_ty, &paths::BTREEMAP) {
|
||||
needs_ref = true;
|
||||
"BTreeMap"
|
||||
} else {
|
||||
|
@ -1760,7 +1759,7 @@ fn lint_get_unwrap<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &hir::Expr, get_a
|
|||
|
||||
fn lint_iter_skip_next(cx: &LateContext<'_, '_>, expr: &hir::Expr) {
|
||||
// lint if caller of skip is an Iterator
|
||||
if match_trait_method(cx, expr, &*paths::ITERATOR) {
|
||||
if match_trait_method(cx, expr, &paths::ITERATOR) {
|
||||
span_lint(
|
||||
cx,
|
||||
ITER_SKIP_NEXT,
|
||||
|
@ -1779,7 +1778,7 @@ fn derefs_to_slice<'a, 'tcx>(
|
|||
match ty.sty {
|
||||
ty::Slice(_) => true,
|
||||
ty::Adt(def, _) if def.is_box() => may_slice(cx, ty.boxed_ty()),
|
||||
ty::Adt(..) => match_type(cx, ty, &*paths::VEC),
|
||||
ty::Adt(..) => match_type(cx, ty, &paths::VEC),
|
||||
ty::Array(_, size) => size.assert_usize(cx.tcx).expect("array length") < 32,
|
||||
ty::Ref(_, inner, _) => may_slice(cx, inner),
|
||||
_ => false,
|
||||
|
@ -1787,7 +1786,7 @@ fn derefs_to_slice<'a, 'tcx>(
|
|||
}
|
||||
|
||||
if let hir::ExprKind::MethodCall(ref path, _, ref args) = expr.node {
|
||||
if path.ident.name == *sym::iter && may_slice(cx, cx.tables.expr_ty(&args[0])) {
|
||||
if path.ident.name == sym!(iter) && may_slice(cx, cx.tables.expr_ty(&args[0])) {
|
||||
Some(&args[0])
|
||||
} else {
|
||||
None
|
||||
|
@ -1812,9 +1811,9 @@ fn derefs_to_slice<'a, 'tcx>(
|
|||
fn lint_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr, unwrap_args: &[hir::Expr]) {
|
||||
let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&unwrap_args[0]));
|
||||
|
||||
let mess = if match_type(cx, obj_ty, &*paths::OPTION) {
|
||||
let mess = if match_type(cx, obj_ty, &paths::OPTION) {
|
||||
Some((OPTION_UNWRAP_USED, "an Option", "None"))
|
||||
} else if match_type(cx, obj_ty, &*paths::RESULT) {
|
||||
} else if match_type(cx, obj_ty, &paths::RESULT) {
|
||||
Some((RESULT_UNWRAP_USED, "a Result", "Err"))
|
||||
} else {
|
||||
None
|
||||
|
@ -1838,7 +1837,7 @@ fn lint_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr, unwrap_args: &[hir::E
|
|||
/// lint use of `ok().expect()` for `Result`s
|
||||
fn lint_ok_expect(cx: &LateContext<'_, '_>, expr: &hir::Expr, ok_args: &[hir::Expr]) {
|
||||
// lint if the caller of `ok()` is a `Result`
|
||||
if match_type(cx, cx.tables.expr_ty(&ok_args[0]), &*paths::RESULT) {
|
||||
if match_type(cx, cx.tables.expr_ty(&ok_args[0]), &paths::RESULT) {
|
||||
let result_type = cx.tables.expr_ty(&ok_args[0]);
|
||||
if let Some(error_type) = get_error_type(cx, result_type) {
|
||||
if has_debug_impl(error_type, cx) {
|
||||
|
@ -1856,7 +1855,7 @@ fn lint_ok_expect(cx: &LateContext<'_, '_>, expr: &hir::Expr, ok_args: &[hir::Ex
|
|||
/// lint use of `map().flatten()` for `Iterators`
|
||||
fn lint_map_flatten<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, map_args: &'tcx [hir::Expr]) {
|
||||
// lint if caller of `.map().flatten()` is an Iterator
|
||||
if match_trait_method(cx, expr, &*paths::ITERATOR) {
|
||||
if match_trait_method(cx, expr, &paths::ITERATOR) {
|
||||
let msg = "called `map(..).flatten()` on an `Iterator`. \
|
||||
This is more succinctly expressed by calling `.flat_map(..)`";
|
||||
let self_snippet = snippet(cx, map_args[0].span, "..");
|
||||
|
@ -1881,8 +1880,8 @@ fn lint_map_unwrap_or_else<'a, 'tcx>(
|
|||
unwrap_args: &'tcx [hir::Expr],
|
||||
) {
|
||||
// lint if the caller of `map()` is an `Option`
|
||||
let is_option = match_type(cx, cx.tables.expr_ty(&map_args[0]), &*paths::OPTION);
|
||||
let is_result = match_type(cx, cx.tables.expr_ty(&map_args[0]), &*paths::RESULT);
|
||||
let is_option = match_type(cx, cx.tables.expr_ty(&map_args[0]), &paths::OPTION);
|
||||
let is_result = match_type(cx, cx.tables.expr_ty(&map_args[0]), &paths::RESULT);
|
||||
if is_option || is_result {
|
||||
// lint message
|
||||
let msg = if is_option {
|
||||
|
@ -1934,10 +1933,10 @@ fn lint_map_unwrap_or_else<'a, 'tcx>(
|
|||
|
||||
/// lint use of `_.map_or(None, _)` for `Option`s
|
||||
fn lint_map_or_none<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, map_or_args: &'tcx [hir::Expr]) {
|
||||
if match_type(cx, cx.tables.expr_ty(&map_or_args[0]), &*paths::OPTION) {
|
||||
if match_type(cx, cx.tables.expr_ty(&map_or_args[0]), &paths::OPTION) {
|
||||
// check if the first non-self argument to map_or() is None
|
||||
let map_or_arg_is_none = if let hir::ExprKind::Path(ref qpath) = map_or_args[1].node {
|
||||
match_qpath(qpath, &*paths::OPTION_NONE)
|
||||
match_qpath(qpath, &paths::OPTION_NONE)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
@ -1964,7 +1963,7 @@ fn lint_map_or_none<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr,
|
|||
/// lint use of `filter().next()` for `Iterators`
|
||||
fn lint_filter_next<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, filter_args: &'tcx [hir::Expr]) {
|
||||
// lint if caller of `.filter().next()` is an Iterator
|
||||
if match_trait_method(cx, expr, &*paths::ITERATOR) {
|
||||
if match_trait_method(cx, expr, &paths::ITERATOR) {
|
||||
let msg = "called `filter(p).next()` on an `Iterator`. This is more succinctly expressed by calling \
|
||||
`.find(p)` instead.";
|
||||
let filter_snippet = snippet(cx, filter_args[1].span, "..");
|
||||
|
@ -1992,7 +1991,7 @@ fn lint_filter_map<'a, 'tcx>(
|
|||
_map_args: &'tcx [hir::Expr],
|
||||
) {
|
||||
// lint if caller of `.filter().map()` is an Iterator
|
||||
if match_trait_method(cx, expr, &*paths::ITERATOR) {
|
||||
if match_trait_method(cx, expr, &paths::ITERATOR) {
|
||||
let msg = "called `filter(p).map(q)` on an `Iterator`. \
|
||||
This is more succinctly expressed by calling `.filter_map(..)` instead.";
|
||||
span_lint(cx, FILTER_MAP, expr.span, msg);
|
||||
|
@ -2001,7 +2000,7 @@ fn lint_filter_map<'a, 'tcx>(
|
|||
|
||||
/// lint use of `filter_map().next()` for `Iterators`
|
||||
fn lint_filter_map_next<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, filter_args: &'tcx [hir::Expr]) {
|
||||
if match_trait_method(cx, expr, &*paths::ITERATOR) {
|
||||
if match_trait_method(cx, expr, &paths::ITERATOR) {
|
||||
let msg = "called `filter_map(p).next()` on an `Iterator`. This is more succinctly expressed by calling \
|
||||
`.find_map(p)` instead.";
|
||||
let filter_snippet = snippet(cx, filter_args[1].span, "..");
|
||||
|
@ -2028,7 +2027,7 @@ fn lint_find_map<'a, 'tcx>(
|
|||
map_args: &'tcx [hir::Expr],
|
||||
) {
|
||||
// lint if caller of `.filter().map()` is an Iterator
|
||||
if match_trait_method(cx, &map_args[0], &*paths::ITERATOR) {
|
||||
if match_trait_method(cx, &map_args[0], &paths::ITERATOR) {
|
||||
let msg = "called `find(p).map(q)` on an `Iterator`. \
|
||||
This is more succinctly expressed by calling `.find_map(..)` instead.";
|
||||
span_lint(cx, FIND_MAP, expr.span, msg);
|
||||
|
@ -2043,7 +2042,7 @@ fn lint_filter_map_map<'a, 'tcx>(
|
|||
_map_args: &'tcx [hir::Expr],
|
||||
) {
|
||||
// lint if caller of `.filter().map()` is an Iterator
|
||||
if match_trait_method(cx, expr, &*paths::ITERATOR) {
|
||||
if match_trait_method(cx, expr, &paths::ITERATOR) {
|
||||
let msg = "called `filter_map(p).map(q)` on an `Iterator`. \
|
||||
This is more succinctly expressed by only calling `.filter_map(..)` instead.";
|
||||
span_lint(cx, FILTER_MAP, expr.span, msg);
|
||||
|
@ -2058,7 +2057,7 @@ fn lint_filter_flat_map<'a, 'tcx>(
|
|||
_map_args: &'tcx [hir::Expr],
|
||||
) {
|
||||
// lint if caller of `.filter().flat_map()` is an Iterator
|
||||
if match_trait_method(cx, expr, &*paths::ITERATOR) {
|
||||
if match_trait_method(cx, expr, &paths::ITERATOR) {
|
||||
let msg = "called `filter(p).flat_map(q)` on an `Iterator`. \
|
||||
This is more succinctly expressed by calling `.flat_map(..)` \
|
||||
and filtering by returning an empty Iterator.";
|
||||
|
@ -2074,7 +2073,7 @@ fn lint_filter_map_flat_map<'a, 'tcx>(
|
|||
_map_args: &'tcx [hir::Expr],
|
||||
) {
|
||||
// lint if caller of `.filter_map().flat_map()` is an Iterator
|
||||
if match_trait_method(cx, expr, &*paths::ITERATOR) {
|
||||
if match_trait_method(cx, expr, &paths::ITERATOR) {
|
||||
let msg = "called `filter_map(p).flat_map(q)` on an `Iterator`. \
|
||||
This is more succinctly expressed by calling `.flat_map(..)` \
|
||||
and filtering by returning an empty Iterator.";
|
||||
|
@ -2091,7 +2090,7 @@ fn lint_search_is_some<'a, 'tcx>(
|
|||
is_some_args: &'tcx [hir::Expr],
|
||||
) {
|
||||
// lint if caller of search is an Iterator
|
||||
if match_trait_method(cx, &is_some_args[0], &*paths::ITERATOR) {
|
||||
if match_trait_method(cx, &is_some_args[0], &paths::ITERATOR) {
|
||||
let msg = format!(
|
||||
"called `is_some()` after searching an `Iterator` with {}. This is more succinctly \
|
||||
expressed by calling `any()`.",
|
||||
|
@ -2164,7 +2163,7 @@ fn lint_binary_expr_with_method_call(cx: &LateContext<'_, '_>, info: &mut Binary
|
|||
fn lint_chars_cmp(
|
||||
cx: &LateContext<'_, '_>,
|
||||
info: &BinaryExprInfo<'_>,
|
||||
chain_methods: &[Symbol],
|
||||
chain_methods: &[&str],
|
||||
lint: &'static Lint,
|
||||
suggest: &str,
|
||||
) -> bool {
|
||||
|
@ -2174,7 +2173,7 @@ fn lint_chars_cmp(
|
|||
if arg_char.len() == 1;
|
||||
if let hir::ExprKind::Path(ref qpath) = fun.node;
|
||||
if let Some(segment) = single_segment_path(qpath);
|
||||
if segment.ident.name == *sym::Some;
|
||||
if segment.ident.name == sym!(Some);
|
||||
then {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
let self_ty = walk_ptrs_ty(cx.tables.expr_ty_adjusted(&args[0][0]));
|
||||
|
@ -2206,15 +2205,15 @@ fn lint_chars_cmp(
|
|||
|
||||
/// Checks for the `CHARS_NEXT_CMP` lint.
|
||||
fn lint_chars_next_cmp<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprInfo<'_>) -> bool {
|
||||
lint_chars_cmp(cx, info, &[*sym::chars, *sym::next], CHARS_NEXT_CMP, "starts_with")
|
||||
lint_chars_cmp(cx, info, &["chars", "next"], CHARS_NEXT_CMP, "starts_with")
|
||||
}
|
||||
|
||||
/// Checks for the `CHARS_LAST_CMP` lint.
|
||||
fn lint_chars_last_cmp<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprInfo<'_>) -> bool {
|
||||
if lint_chars_cmp(cx, info, &[*sym::chars, *sym::last], CHARS_LAST_CMP, "ends_with") {
|
||||
if lint_chars_cmp(cx, info, &["chars", "last"], CHARS_LAST_CMP, "ends_with") {
|
||||
true
|
||||
} else {
|
||||
lint_chars_cmp(cx, info, &[*sym::chars, *sym::next_back], CHARS_LAST_CMP, "ends_with")
|
||||
lint_chars_cmp(cx, info, &["chars", "next_back"], CHARS_LAST_CMP, "ends_with")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2222,7 +2221,7 @@ fn lint_chars_last_cmp<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprIn
|
|||
fn lint_chars_cmp_with_unwrap<'a, 'tcx>(
|
||||
cx: &LateContext<'a, 'tcx>,
|
||||
info: &BinaryExprInfo<'_>,
|
||||
chain_methods: &[Symbol],
|
||||
chain_methods: &[&str],
|
||||
lint: &'static Lint,
|
||||
suggest: &str,
|
||||
) -> bool {
|
||||
|
@ -2258,7 +2257,7 @@ fn lint_chars_next_cmp_with_unwrap<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &
|
|||
lint_chars_cmp_with_unwrap(
|
||||
cx,
|
||||
info,
|
||||
&[*sym::chars, *sym::next, *sym::unwrap],
|
||||
&["chars", "next", "unwrap"],
|
||||
CHARS_NEXT_CMP,
|
||||
"starts_with",
|
||||
)
|
||||
|
@ -2269,7 +2268,7 @@ fn lint_chars_last_cmp_with_unwrap<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &
|
|||
if lint_chars_cmp_with_unwrap(
|
||||
cx,
|
||||
info,
|
||||
&[*sym::chars, *sym::last, *sym::unwrap],
|
||||
&["chars", "last", "unwrap"],
|
||||
CHARS_LAST_CMP,
|
||||
"ends_with",
|
||||
) {
|
||||
|
@ -2278,7 +2277,7 @@ fn lint_chars_last_cmp_with_unwrap<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &
|
|||
lint_chars_cmp_with_unwrap(
|
||||
cx,
|
||||
info,
|
||||
&[*sym::chars, *sym::next_back, *sym::unwrap],
|
||||
&["chars", "next_back", "unwrap"],
|
||||
CHARS_LAST_CMP,
|
||||
"ends_with",
|
||||
)
|
||||
|
@ -2313,7 +2312,7 @@ fn lint_single_char_pattern<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, _expr: &'tcx h
|
|||
fn lint_asref(cx: &LateContext<'_, '_>, expr: &hir::Expr, call_name: &str, as_ref_args: &[hir::Expr]) {
|
||||
// when we get here, we've already checked that the call name is "as_ref" or "as_mut"
|
||||
// check if the call is to the actual `AsRef` or `AsMut` trait
|
||||
if match_trait_method(cx, expr, &*paths::ASREF_TRAIT) || match_trait_method(cx, expr, &*paths::ASMUT_TRAIT) {
|
||||
if match_trait_method(cx, expr, &paths::ASREF_TRAIT) || match_trait_method(cx, expr, &paths::ASMUT_TRAIT) {
|
||||
// check if the type after `as_ref` or `as_mut` is the same as before
|
||||
let recvr = &as_ref_args[0];
|
||||
let rcv_ty = cx.tables.expr_ty(recvr);
|
||||
|
@ -2345,9 +2344,9 @@ fn lint_asref(cx: &LateContext<'_, '_>, expr: &hir::Expr, call_name: &str, as_re
|
|||
}
|
||||
}
|
||||
|
||||
fn ty_has_iter_method(cx: &LateContext<'_, '_>, self_ref_ty: Ty<'_>) -> Option<(&'static Lint, Symbol, &'static str)> {
|
||||
fn ty_has_iter_method(cx: &LateContext<'_, '_>, self_ref_ty: Ty<'_>) -> Option<(&'static Lint, &'static str, &'static str)> {
|
||||
if let Some(ty_name) = has_iter_method(cx, self_ref_ty) {
|
||||
let lint = if ty_name == *sym::array || ty_name == *sym::PathBuf {
|
||||
let lint = if ty_name == "array" || ty_name == "PathBuf" {
|
||||
INTO_ITER_ON_ARRAY
|
||||
} else {
|
||||
INTO_ITER_ON_REF
|
||||
|
@ -2367,7 +2366,7 @@ fn ty_has_iter_method(cx: &LateContext<'_, '_>, self_ref_ty: Ty<'_>) -> Option<(
|
|||
}
|
||||
|
||||
fn lint_into_iter(cx: &LateContext<'_, '_>, expr: &hir::Expr, self_ref_ty: Ty<'_>, method_span: Span) {
|
||||
if !match_trait_method(cx, expr, &*paths::INTO_ITERATOR) {
|
||||
if !match_trait_method(cx, expr, &paths::INTO_ITERATOR) {
|
||||
return;
|
||||
}
|
||||
if let Some((lint, kind, method_name)) = ty_has_iter_method(cx, self_ref_ty) {
|
||||
|
@ -2389,7 +2388,7 @@ fn lint_into_iter(cx: &LateContext<'_, '_>, expr: &hir::Expr, self_ref_ty: Ty<'_
|
|||
/// Given a `Result<T, E>` type, return its error type (`E`).
|
||||
fn get_error_type<'a>(cx: &LateContext<'_, '_>, ty: Ty<'a>) -> Option<Ty<'a>> {
|
||||
if let ty::Adt(_, substs) = ty.sty {
|
||||
if match_type(cx, ty, &*paths::RESULT) {
|
||||
if match_type(cx, ty, &paths::RESULT) {
|
||||
substs.types().nth(1)
|
||||
} else {
|
||||
None
|
||||
|
@ -2426,59 +2425,59 @@ const CONVENTIONS: [(Convention, &[SelfKind]); 7] = [
|
|||
#[rustfmt::skip]
|
||||
lazy_static! {
|
||||
static ref TRAIT_METHODS: [(Symbol, usize, SelfKind, OutType, &'static str); 30] = [
|
||||
(*sym::add, 2, SelfKind::Value, OutType::Any, "std::ops::Add"),
|
||||
(*sym::as_mut, 1, SelfKind::RefMut, OutType::Ref, "std::convert::AsMut"),
|
||||
(*sym::as_ref, 1, SelfKind::Ref, OutType::Ref, "std::convert::AsRef"),
|
||||
(*sym::bitand, 2, SelfKind::Value, OutType::Any, "std::ops::BitAnd"),
|
||||
(*sym::bitor, 2, SelfKind::Value, OutType::Any, "std::ops::BitOr"),
|
||||
(*sym::bitxor, 2, SelfKind::Value, OutType::Any, "std::ops::BitXor"),
|
||||
(*sym::borrow, 1, SelfKind::Ref, OutType::Ref, "std::borrow::Borrow"),
|
||||
(*sym::borrow_mut, 1, SelfKind::RefMut, OutType::Ref, "std::borrow::BorrowMut"),
|
||||
(*sym::clone, 1, SelfKind::Ref, OutType::Any, "std::clone::Clone"),
|
||||
(*sym::cmp, 2, SelfKind::Ref, OutType::Any, "std::cmp::Ord"),
|
||||
(*sym::default, 0, SelfKind::No, OutType::Any, "std::default::Default"),
|
||||
(*sym::deref, 1, SelfKind::Ref, OutType::Ref, "std::ops::Deref"),
|
||||
(*sym::deref_mut, 1, SelfKind::RefMut, OutType::Ref, "std::ops::DerefMut"),
|
||||
(*sym::div, 2, SelfKind::Value, OutType::Any, "std::ops::Div"),
|
||||
(*sym::drop, 1, SelfKind::RefMut, OutType::Unit, "std::ops::Drop"),
|
||||
(*sym::eq, 2, SelfKind::Ref, OutType::Bool, "std::cmp::PartialEq"),
|
||||
(*sym::from_iter, 1, SelfKind::No, OutType::Any, "std::iter::FromIterator"),
|
||||
(*sym::from_str, 1, SelfKind::No, OutType::Any, "std::str::FromStr"),
|
||||
(*sym::hash, 2, SelfKind::Ref, OutType::Unit, "std::hash::Hash"),
|
||||
(*sym::index, 2, SelfKind::Ref, OutType::Ref, "std::ops::Index"),
|
||||
(*sym::index_mut, 2, SelfKind::RefMut, OutType::Ref, "std::ops::IndexMut"),
|
||||
(*sym::into_iter, 1, SelfKind::Value, OutType::Any, "std::iter::IntoIterator"),
|
||||
(*sym::mul, 2, SelfKind::Value, OutType::Any, "std::ops::Mul"),
|
||||
(*sym::neg, 1, SelfKind::Value, OutType::Any, "std::ops::Neg"),
|
||||
(*sym::next, 1, SelfKind::RefMut, OutType::Any, "std::iter::Iterator"),
|
||||
(*sym::not, 1, SelfKind::Value, OutType::Any, "std::ops::Not"),
|
||||
(*sym::rem, 2, SelfKind::Value, OutType::Any, "std::ops::Rem"),
|
||||
(*sym::shl, 2, SelfKind::Value, OutType::Any, "std::ops::Shl"),
|
||||
(*sym::shr, 2, SelfKind::Value, OutType::Any, "std::ops::Shr"),
|
||||
(*sym::sub, 2, SelfKind::Value, OutType::Any, "std::ops::Sub"),
|
||||
(sym!(add), 2, SelfKind::Value, OutType::Any, "std::ops::Add"),
|
||||
(sym!(as_mut), 1, SelfKind::RefMut, OutType::Ref, "std::convert::AsMut"),
|
||||
(sym!(as_ref), 1, SelfKind::Ref, OutType::Ref, "std::convert::AsRef"),
|
||||
(sym!(bitand), 2, SelfKind::Value, OutType::Any, "std::ops::BitAnd"),
|
||||
(sym!(bitor), 2, SelfKind::Value, OutType::Any, "std::ops::BitOr"),
|
||||
(sym!(bitxor), 2, SelfKind::Value, OutType::Any, "std::ops::BitXor"),
|
||||
(sym!(borrow), 1, SelfKind::Ref, OutType::Ref, "std::borrow::Borrow"),
|
||||
(sym!(borrow_mut), 1, SelfKind::RefMut, OutType::Ref, "std::borrow::BorrowMut"),
|
||||
(sym!(clone), 1, SelfKind::Ref, OutType::Any, "std::clone::Clone"),
|
||||
(sym!(cmp), 2, SelfKind::Ref, OutType::Any, "std::cmp::Ord"),
|
||||
(sym!(default), 0, SelfKind::No, OutType::Any, "std::default::Default"),
|
||||
(sym!(deref), 1, SelfKind::Ref, OutType::Ref, "std::ops::Deref"),
|
||||
(sym!(deref_mut), 1, SelfKind::RefMut, OutType::Ref, "std::ops::DerefMut"),
|
||||
(sym!(div), 2, SelfKind::Value, OutType::Any, "std::ops::Div"),
|
||||
(sym!(drop), 1, SelfKind::RefMut, OutType::Unit, "std::ops::Drop"),
|
||||
(sym!(eq), 2, SelfKind::Ref, OutType::Bool, "std::cmp::PartialEq"),
|
||||
(sym!(from_iter), 1, SelfKind::No, OutType::Any, "std::iter::FromIterator"),
|
||||
(sym!(from_str), 1, SelfKind::No, OutType::Any, "std::str::FromStr"),
|
||||
(sym!(hash), 2, SelfKind::Ref, OutType::Unit, "std::hash::Hash"),
|
||||
(sym!(index), 2, SelfKind::Ref, OutType::Ref, "std::ops::Index"),
|
||||
(sym!(index_mut), 2, SelfKind::RefMut, OutType::Ref, "std::ops::IndexMut"),
|
||||
(sym!(into_iter), 1, SelfKind::Value, OutType::Any, "std::iter::IntoIterator"),
|
||||
(sym!(mul), 2, SelfKind::Value, OutType::Any, "std::ops::Mul"),
|
||||
(sym!(neg), 1, SelfKind::Value, OutType::Any, "std::ops::Neg"),
|
||||
(sym!(next), 1, SelfKind::RefMut, OutType::Any, "std::iter::Iterator"),
|
||||
(sym!(not), 1, SelfKind::Value, OutType::Any, "std::ops::Not"),
|
||||
(sym!(rem), 2, SelfKind::Value, OutType::Any, "std::ops::Rem"),
|
||||
(sym!(shl), 2, SelfKind::Value, OutType::Any, "std::ops::Shl"),
|
||||
(sym!(shr), 2, SelfKind::Value, OutType::Any, "std::ops::Shr"),
|
||||
(sym!(sub), 2, SelfKind::Value, OutType::Any, "std::ops::Sub"),
|
||||
];
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
lazy_static! {
|
||||
static ref PATTERN_METHODS: [(Symbol, usize); 17] = [
|
||||
(*sym::contains, 1),
|
||||
(*sym::starts_with, 1),
|
||||
(*sym::ends_with, 1),
|
||||
(*sym::find, 1),
|
||||
(*sym::rfind, 1),
|
||||
(*sym::split, 1),
|
||||
(*sym::rsplit, 1),
|
||||
(*sym::split_terminator, 1),
|
||||
(*sym::rsplit_terminator, 1),
|
||||
(*sym::splitn, 2),
|
||||
(*sym::rsplitn, 2),
|
||||
(*sym::matches, 1),
|
||||
(*sym::rmatches, 1),
|
||||
(*sym::match_indices, 1),
|
||||
(*sym::rmatch_indices, 1),
|
||||
(*sym::trim_start_matches, 1),
|
||||
(*sym::trim_end_matches, 1),
|
||||
(sym!(contains), 1),
|
||||
(sym!(starts_with), 1),
|
||||
(sym!(ends_with), 1),
|
||||
(sym!(find), 1),
|
||||
(sym!(rfind), 1),
|
||||
(sym!(split), 1),
|
||||
(sym!(rsplit), 1),
|
||||
(sym!(split_terminator), 1),
|
||||
(sym!(rsplit_terminator), 1),
|
||||
(sym!(splitn), 2),
|
||||
(sym!(rsplitn), 2),
|
||||
(sym!(matches), 1),
|
||||
(sym!(rmatches), 1),
|
||||
(sym!(match_indices), 1),
|
||||
(sym!(rmatch_indices), 1),
|
||||
(sym!(trim_start_matches), 1),
|
||||
(sym!(trim_end_matches), 1),
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -2536,8 +2535,8 @@ impl SelfKind {
|
|||
} else {
|
||||
match self {
|
||||
SelfKind::Value => false,
|
||||
SelfKind::Ref => is_as_ref_or_mut_trait(ty, self_ty, generics, &*paths::ASREF_TRAIT),
|
||||
SelfKind::RefMut => is_as_ref_or_mut_trait(ty, self_ty, generics, &*paths::ASMUT_TRAIT),
|
||||
SelfKind::Ref => is_as_ref_or_mut_trait(ty, self_ty, generics, &paths::ASREF_TRAIT),
|
||||
SelfKind::RefMut => is_as_ref_or_mut_trait(ty, self_ty, generics, &paths::ASMUT_TRAIT),
|
||||
SelfKind::No => true,
|
||||
}
|
||||
}
|
||||
|
@ -2553,7 +2552,7 @@ impl SelfKind {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_as_ref_or_mut_trait(ty: &hir::Ty, self_ty: &hir::Ty, generics: &hir::Generics, name: &[Symbol]) -> bool {
|
||||
fn is_as_ref_or_mut_trait(ty: &hir::Ty, self_ty: &hir::Ty, generics: &hir::Generics, name: &[&str]) -> bool {
|
||||
single_segment_ty(ty).map_or(false, |seg| {
|
||||
generics.params.iter().any(|param| match param.kind {
|
||||
hir::GenericParamKind::Type { .. } => {
|
||||
|
@ -2657,7 +2656,7 @@ impl OutType {
|
|||
|
||||
fn is_bool(ty: &hir::Ty) -> bool {
|
||||
if let hir::TyKind::Path(ref p) = ty.node {
|
||||
match_qpath(p, &[*sym::bool])
|
||||
match_qpath(p, &["bool"])
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use rustc::hir::intravisit::{walk_path, NestedVisitorMap, Visitor};
|
|||
use rustc::hir::{self, *};
|
||||
use rustc::lint::LateContext;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax_pos::symbol::Symbol;
|
||||
|
||||
use super::OPTION_MAP_UNWRAP_OR;
|
||||
|
||||
|
@ -16,7 +16,7 @@ pub(super) fn lint<'a, 'tcx>(
|
|||
unwrap_args: &'tcx [hir::Expr],
|
||||
) {
|
||||
// lint if the caller of `map()` is an `Option`
|
||||
if match_type(cx, cx.tables.expr_ty(&map_args[0]), &*paths::OPTION) {
|
||||
if match_type(cx, cx.tables.expr_ty(&map_args[0]), &paths::OPTION) {
|
||||
if !is_copy(cx, cx.tables.expr_ty(&unwrap_args[1])) {
|
||||
// Do not lint if the `map` argument uses identifiers in the `map`
|
||||
// argument that are also used in the `unwrap_or` argument
|
||||
|
|
|
@ -11,7 +11,7 @@ use if_chain::if_chain;
|
|||
use super::UNNECESSARY_FILTER_MAP;
|
||||
|
||||
pub(super) fn lint(cx: &LateContext<'_, '_>, expr: &hir::Expr, args: &[hir::Expr]) {
|
||||
if !match_trait_method(cx, expr, &*paths::ITERATOR) {
|
||||
if !match_trait_method(cx, expr, &paths::ITERATOR) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ fn check_expression<'a, 'tcx: 'a>(
|
|||
if_chain! {
|
||||
if let hir::ExprKind::Path(ref path) = func.node;
|
||||
then {
|
||||
if match_qpath(path, &*paths::OPTION_SOME) {
|
||||
if match_qpath(path, &paths::OPTION_SOME) {
|
||||
if_chain! {
|
||||
if let hir::ExprKind::Path(path) = &args[0].node;
|
||||
if let Res::Local(ref local) = cx.tables.qpath_res(path, args[0].hir_id);
|
||||
|
@ -99,7 +99,7 @@ fn check_expression<'a, 'tcx: 'a>(
|
|||
}
|
||||
(found_mapping, found_filtering)
|
||||
},
|
||||
hir::ExprKind::Path(path) if match_qpath(path, &*paths::OPTION_NONE) => (false, true),
|
||||
hir::ExprKind::Path(path) if match_qpath(path, &paths::OPTION_NONE) => (false, true),
|
||||
_ => (true, true),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,9 +63,9 @@ fn min_max<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr) -> Option<(MinMax, Cons
|
|||
if let ExprKind::Call(ref path, ref args) = expr.node {
|
||||
if let ExprKind::Path(ref qpath) = path.node {
|
||||
cx.tables.qpath_res(qpath, path.hir_id).opt_def_id().and_then(|def_id| {
|
||||
if match_def_path(cx, def_id, &*paths::CMP_MIN) {
|
||||
if match_def_path(cx, def_id, &paths::CMP_MIN) {
|
||||
fetch_const(cx, args, MinMax::Min)
|
||||
} else if match_def_path(cx, def_id, &*paths::CMP_MAX) {
|
||||
} else if match_def_path(cx, def_id, &paths::CMP_MAX) {
|
||||
fetch_const(cx, args, MinMax::Max)
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -11,7 +11,6 @@ use syntax::source_map::{ExpnFormat, Span};
|
|||
|
||||
use crate::consts::{constant, Constant};
|
||||
use crate::utils::sugg::Sugg;
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{
|
||||
get_item_name, get_parent_expr, implements_trait, in_constant, in_macro_or_desugar, is_integer_literal,
|
||||
iter_input_pats, last_path_segment, match_qpath, match_trait_method, paths, snippet, span_lint, span_lint_and_then,
|
||||
|
@ -462,7 +461,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MiscLints {
|
|||
fn check_nan(cx: &LateContext<'_, '_>, path: &Path, expr: &Expr) {
|
||||
if !in_constant(cx, expr.hir_id) {
|
||||
if let Some(seg) = path.segments.last() {
|
||||
if seg.ident.name == *sym::NAN {
|
||||
if seg.ident.name == sym!(NAN) {
|
||||
span_lint(
|
||||
cx,
|
||||
CMP_NAN,
|
||||
|
@ -497,7 +496,7 @@ fn is_float(cx: &LateContext<'_, '_>, expr: &Expr) -> bool {
|
|||
fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr, other: &Expr) {
|
||||
let (arg_ty, snip) = match expr.node {
|
||||
ExprKind::MethodCall(.., ref args) if args.len() == 1 => {
|
||||
if match_trait_method(cx, expr, &*paths::TO_STRING) || match_trait_method(cx, expr, &*paths::TO_OWNED) {
|
||||
if match_trait_method(cx, expr, &paths::TO_STRING) || match_trait_method(cx, expr, &paths::TO_OWNED) {
|
||||
(cx.tables.expr_ty_adjusted(&args[0]), snippet(cx, args[0].span, ".."))
|
||||
} else {
|
||||
return;
|
||||
|
@ -505,7 +504,7 @@ fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr, other: &Expr) {
|
|||
},
|
||||
ExprKind::Call(ref path, ref v) if v.len() == 1 => {
|
||||
if let ExprKind::Path(ref path) = path.node {
|
||||
if match_qpath(path, &[*sym::String, *sym::from_str]) || match_qpath(path, &[*sym::String, *sym::from])
|
||||
if match_qpath(path, &["String", "from_str"]) || match_qpath(path, &["String", "from"])
|
||||
{
|
||||
(cx.tables.expr_ty_adjusted(&v[0]), snippet(cx, v[0].span, ".."))
|
||||
} else {
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
// [`missing_doc`]: https://github.com/rust-lang/rust/blob/d6d05904697d89099b55da3331155392f1db9c00/src/librustc_lint/builtin.rs#L246
|
||||
//
|
||||
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{in_macro_or_desugar, span_lint};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir;
|
||||
|
@ -92,7 +91,7 @@ impl MissingDoc {
|
|||
|
||||
let has_doc = attrs
|
||||
.iter()
|
||||
.any(|a| a.check_name(*sym::doc) && (a.is_value_str() || Self::has_include(a.meta())));
|
||||
.any(|a| a.check_name(sym!(doc)) && (a.is_value_str() || Self::has_include(a.meta())));
|
||||
if !has_doc {
|
||||
span_lint(
|
||||
cx,
|
||||
|
@ -110,10 +109,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
|
|||
fn enter_lint_attrs(&mut self, _: &LateContext<'a, 'tcx>, attrs: &'tcx [ast::Attribute]) {
|
||||
let doc_hidden = self.doc_hidden()
|
||||
|| attrs.iter().any(|attr| {
|
||||
attr.check_name(*sym::doc)
|
||||
attr.check_name(sym!(doc))
|
||||
&& match attr.meta_item_list() {
|
||||
None => false,
|
||||
Some(l) => attr::list_contains_name(&l[..], *sym::hidden),
|
||||
Some(l) => attr::list_contains_name(&l[..], sym!(hidden)),
|
||||
}
|
||||
});
|
||||
self.doc_hidden_stack.push(doc_hidden);
|
||||
|
@ -133,7 +132,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
|
|||
hir::ItemKind::Enum(..) => "an enum",
|
||||
hir::ItemKind::Fn(..) => {
|
||||
// ignore main()
|
||||
if it.ident.name == *sym::main {
|
||||
if it.ident.name == sym!(main) {
|
||||
let def_id = cx.tcx.hir().local_def_id_from_hir_id(it.hir_id);
|
||||
let def_key = cx.tcx.hir().def_key(def_id);
|
||||
if def_key.parent == Some(hir::def_id::CRATE_DEF_INDEX) {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use crate::utils::span_lint;
|
||||
use crate::utils::sym;
|
||||
use rustc::hir;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_lint_pass, declare_tool_lint};
|
||||
|
@ -58,7 +57,7 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
fn check_missing_inline_attrs(cx: &LateContext<'_, '_>, attrs: &[ast::Attribute], sp: Span, desc: &'static str) {
|
||||
let has_inline = attrs.iter().any(|a| a.check_name(*sym::inline));
|
||||
let has_inline = attrs.iter().any(|a| a.check_name(sym!(inline)));
|
||||
if !has_inline {
|
||||
span_lint(
|
||||
cx,
|
||||
|
|
|
@ -55,7 +55,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Mutex {
|
|||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
let ty = cx.tables.expr_ty(expr);
|
||||
if let ty::Adt(_, subst) = ty.sty {
|
||||
if match_type(cx, ty, &*paths::MUTEX) {
|
||||
if match_type(cx, ty, &paths::MUTEX) {
|
||||
let mutex_param = subst.type_at(0);
|
||||
if let Some(atomic_name) = get_atomic_name(mutex_param) {
|
||||
let msg = format!(
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
//!
|
||||
//! This lint is **warn** by default
|
||||
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{in_macro_or_desugar, snippet_opt, span_lint_and_then};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir::{BindingAnnotation, Expr, ExprKind, HirId, Item, MutImmutable, Pat, PatKind};
|
||||
|
@ -109,7 +108,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow {
|
|||
}
|
||||
|
||||
fn check_item(&mut self, _: &LateContext<'a, 'tcx>, item: &'tcx Item) {
|
||||
if item.attrs.iter().any(|a| a.check_name(*sym::automatically_derived)) {
|
||||
if item.attrs.iter().any(|a| a.check_name(sym!(automatically_derived))) {
|
||||
debug_assert!(self.derived_item.is_none());
|
||||
self.derived_item = Some(item.hir_id);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use crate::utils::ptr::get_spans;
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{
|
||||
get_trait_def_id, implements_trait, in_macro_or_desugar, is_copy, is_self, match_type, multispan_sugg, paths,
|
||||
snippet, snippet_opt, span_lint_and_then,
|
||||
|
@ -102,12 +101,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
|||
}
|
||||
|
||||
// Allow `Borrow` or functions to be taken by value
|
||||
let borrow_trait = need!(get_trait_def_id(cx, &*paths::BORROW_TRAIT));
|
||||
let borrow_trait = need!(get_trait_def_id(cx, &paths::BORROW_TRAIT));
|
||||
let whitelisted_traits = [
|
||||
need!(cx.tcx.lang_items().fn_trait()),
|
||||
need!(cx.tcx.lang_items().fn_once_trait()),
|
||||
need!(cx.tcx.lang_items().fn_mut_trait()),
|
||||
need!(get_trait_def_id(cx, &*paths::RANGE_ARGUMENT_TRAIT)),
|
||||
need!(get_trait_def_id(cx, &paths::RANGE_ARGUMENT_TRAIT)),
|
||||
];
|
||||
|
||||
let sized_trait = need!(cx.tcx.lang_items().sized_trait());
|
||||
|
@ -215,12 +214,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
|||
|
||||
let deref_span = spans_need_deref.get(&canonical_id);
|
||||
if_chain! {
|
||||
if match_type(cx, ty, &*paths::VEC);
|
||||
if match_type(cx, ty, &paths::VEC);
|
||||
if let Some(clone_spans) =
|
||||
get_spans(cx, Some(body.id()), idx, &[(*sym::clone, ".to_owned()")]);
|
||||
get_spans(cx, Some(body.id()), idx, &[("clone", ".to_owned()")]);
|
||||
if let TyKind::Path(QPath::Resolved(_, ref path)) = input.node;
|
||||
if let Some(elem_ty) = path.segments.iter()
|
||||
.find(|seg| seg.ident.name == *sym::Vec)
|
||||
.find(|seg| seg.ident.name == sym!(Vec))
|
||||
.and_then(|ps| ps.args.as_ref())
|
||||
.map(|params| params.args.iter().find_map(|arg| match arg {
|
||||
GenericArg::Type(ty) => Some(ty),
|
||||
|
@ -254,9 +253,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
|||
}
|
||||
}
|
||||
|
||||
if match_type(cx, ty, &*paths::STRING) {
|
||||
if match_type(cx, ty, &paths::STRING) {
|
||||
if let Some(clone_spans) =
|
||||
get_spans(cx, Some(body.id()), idx, &[(*sym::clone, ".to_string()"), (*sym::as_str, "")]) {
|
||||
get_spans(cx, Some(body.id()), idx, &[("clone", ".to_string()"), ("as_str", "")]) {
|
||||
db.span_suggestion(
|
||||
input.span,
|
||||
"consider changing the type to",
|
||||
|
@ -313,7 +312,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
|||
/// Functions marked with these attributes must have the exact signature.
|
||||
fn requires_exact_signature(attrs: &[Attribute]) -> bool {
|
||||
attrs.iter().any(|attr| {
|
||||
[*sym::proc_macro, *sym::proc_macro_attribute, *sym::proc_macro_derive]
|
||||
[sym!(proc_macro), sym!(proc_macro_attribute), sym!(proc_macro_derive)]
|
||||
.iter()
|
||||
.any(|&allow| attr.check_name(allow))
|
||||
})
|
||||
|
|
|
@ -58,7 +58,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NoNegCompOpForPartialOrd {
|
|||
let ty = cx.tables.expr_ty(left);
|
||||
|
||||
let implements_ord = {
|
||||
if let Some(id) = utils::get_trait_def_id(cx, &*paths::ORD) {
|
||||
if let Some(id) = utils::get_trait_def_id(cx, &paths::ORD) {
|
||||
utils::implements_trait(cx, ty, id, &[])
|
||||
} else {
|
||||
return;
|
||||
|
@ -66,7 +66,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NoNegCompOpForPartialOrd {
|
|||
};
|
||||
|
||||
let implements_partial_ord = {
|
||||
if let Some(id) = utils::get_trait_def_id(cx, &*paths::PARTIAL_ORD) {
|
||||
if let Some(id) = utils::get_trait_def_id(cx, &paths::PARTIAL_ORD) {
|
||||
utils::implements_trait(cx, ty, id, &[])
|
||||
} else {
|
||||
return;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use crate::utils::paths;
|
||||
use crate::utils::sugg::DiagnosticBuilderExt;
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{get_trait_def_id, implements_trait, return_ty, same_tys, span_lint_hir_and_then};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir;
|
||||
|
@ -121,12 +120,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NewWithoutDefault {
|
|||
// impl of `Default`
|
||||
return;
|
||||
}
|
||||
if sig.decl.inputs.is_empty() && name == *sym::new && cx.access_levels.is_reachable(id) {
|
||||
if sig.decl.inputs.is_empty() && name == sym!(new) && cx.access_levels.is_reachable(id) {
|
||||
let self_did = cx.tcx.hir().local_def_id_from_hir_id(cx.tcx.hir().get_parent_item(id));
|
||||
let self_ty = cx.tcx.type_of(self_did);
|
||||
if_chain! {
|
||||
if same_tys(cx, self_ty, return_ty(cx, id));
|
||||
if let Some(default_trait_id) = get_trait_def_id(cx, &*paths::DEFAULT_TRAIT);
|
||||
if let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT);
|
||||
then {
|
||||
if self.impling_types.is_none() {
|
||||
let mut impls = NodeSet::default();
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::utils::sym;
|
||||
use crate::utils::{span_lint, span_lint_and_then};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, impl_lint_pass};
|
||||
|
@ -356,7 +355,7 @@ impl EarlyLintPass for NonExpressiveNames {
|
|||
}
|
||||
|
||||
fn do_check(lint: &mut NonExpressiveNames, cx: &EarlyContext<'_>, attrs: &[Attribute], decl: &FnDecl, blk: &Block) {
|
||||
if !attr::contains_name(attrs, *sym::test) {
|
||||
if !attr::contains_name(attrs, sym!(test)) {
|
||||
let mut visitor = SimilarNamesLocalVisitor {
|
||||
names: Vec::new(),
|
||||
cx,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::utils::sym;
|
||||
use crate::utils::{match_type, method_chain_args, paths, snippet, span_help_and_lint};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir::*;
|
||||
|
@ -44,10 +43,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OkIfLet {
|
|||
if let MatchSource::IfLetDesugar { .. } = *source; //test if it is an If Let
|
||||
if let ExprKind::MethodCall(_, _, ref result_types) = op.node; //check is expr.ok() has type Result<T,E>.ok()
|
||||
if let PatKind::TupleStruct(QPath::Resolved(_, ref x), ref y, _) = body[0].pats[0].node; //get operation
|
||||
if method_chain_args(op, &[*sym::ok]).is_some(); //test to see if using ok() methoduse std::marker::Sized;
|
||||
if method_chain_args(op, &["ok"]).is_some(); //test to see if using ok() methoduse std::marker::Sized;
|
||||
|
||||
then {
|
||||
let is_result_type = match_type(cx, cx.tables.expr_ty(&result_types[0]), &*paths::RESULT);
|
||||
let is_result_type = match_type(cx, cx.tables.expr_ty(&result_types[0]), &paths::RESULT);
|
||||
let some_expr_string = snippet(cx, y[0].span, "");
|
||||
if print::to_string(print::NO_ANN, |s| s.print_path(x, false)) == "Some" && is_result_type {
|
||||
span_help_and_lint(cx, IF_LET_SOME_RESULT, expr.span,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::utils::sym;
|
||||
use crate::utils::{match_type, paths, span_lint, walk_ptrs_ty};
|
||||
use rustc::hir::{Expr, ExprKind};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
|
@ -32,7 +31,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OpenOptions {
|
|||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
||||
if let ExprKind::MethodCall(ref path, _, ref arguments) = e.node {
|
||||
let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&arguments[0]));
|
||||
if path.ident.name == *sym::open && match_type(cx, obj_ty, &*paths::OPEN_OPTIONS) {
|
||||
if path.ident.name == sym!(open) && match_type(cx, obj_ty, &paths::OPEN_OPTIONS) {
|
||||
let mut options = Vec::new();
|
||||
get_open_options(cx, &arguments[0], &mut options);
|
||||
check_open_options(cx, &options, e.span);
|
||||
|
@ -62,7 +61,7 @@ fn get_open_options(cx: &LateContext<'_, '_>, argument: &Expr, options: &mut Vec
|
|||
let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&arguments[0]));
|
||||
|
||||
// Only proceed if this is a call on some object of type std::fs::OpenOptions
|
||||
if match_type(cx, obj_ty, &*paths::OPEN_OPTIONS) && arguments.len() >= 2 {
|
||||
if match_type(cx, obj_ty, &paths::OPEN_OPTIONS) && arguments.len() >= 2 {
|
||||
let argument_option = match arguments[1].node {
|
||||
ExprKind::Lit(ref span) => {
|
||||
if let Spanned {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::utils::sym;
|
||||
use crate::utils::{is_direct_expn_of, is_expn_of, match_def_path, paths, resolve_node, span_lint};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir::*;
|
||||
|
@ -53,10 +52,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PanicUnimplemented {
|
|||
if let ExprKind::Call(ref fun, ref params) = ex.node;
|
||||
if let ExprKind::Path(ref qpath) = fun.node;
|
||||
if let Some(fun_def_id) = resolve_node(cx, qpath, fun.hir_id).opt_def_id();
|
||||
if match_def_path(cx, fun_def_id, &*paths::BEGIN_PANIC);
|
||||
if match_def_path(cx, fun_def_id, &paths::BEGIN_PANIC);
|
||||
if params.len() == 2;
|
||||
then {
|
||||
if is_expn_of(expr.span, *sym::unimplemented).is_some() {
|
||||
if is_expn_of(expr.span, "unimplemented").is_some() {
|
||||
let span = get_outer_span(expr);
|
||||
span_lint(cx, UNIMPLEMENTED, span,
|
||||
"`unimplemented` should not be present in production code");
|
||||
|
@ -83,7 +82,7 @@ fn get_outer_span(expr: &Expr) -> Span {
|
|||
fn match_panic(params: &P<[Expr]>, expr: &Expr, cx: &LateContext<'_, '_>) {
|
||||
if_chain! {
|
||||
if let ExprKind::Lit(ref lit) = params[0].node;
|
||||
if is_direct_expn_of(expr.span, *sym::panic).is_some();
|
||||
if is_direct_expn_of(expr.span, "panic").is_some();
|
||||
if let LitKind::Str(ref string, _) = lit.node;
|
||||
let string = string.as_str().replace("{{", "").replace("}}", "");
|
||||
if let Some(par) = string.find('{');
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::utils::sym;
|
||||
use crate::utils::{is_automatically_derived, span_lint_hir};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir::*;
|
||||
|
@ -40,7 +39,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PartialEqNeImpl {
|
|||
if trait_ref.path.res.def_id() == eq_trait;
|
||||
then {
|
||||
for impl_item in impl_items {
|
||||
if impl_item.ident.name == *sym::ne {
|
||||
if impl_item.ident.name == sym!(ne) {
|
||||
span_lint_hir(
|
||||
cx,
|
||||
PARTIALEQ_NE_IMPL,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::utils::sym;
|
||||
use crate::utils::{match_type, paths, span_lint_and_sugg, walk_ptrs_ty};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir::*;
|
||||
|
@ -45,9 +44,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PathBufPushOverwrite {
|
|||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
if_chain! {
|
||||
if let ExprKind::MethodCall(ref path, _, ref args) = expr.node;
|
||||
if path.ident.name == *sym::push;
|
||||
if path.ident.name == sym!(push);
|
||||
if args.len() == 2;
|
||||
if match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(&args[0])), &*paths::PATH_BUF);
|
||||
if match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(&args[0])), &paths::PATH_BUF);
|
||||
if let Some(get_index_arg) = args.get(1);
|
||||
if let ExprKind::Lit(ref lit) = get_index_arg.node;
|
||||
if let LitKind::Str(ref path_lit, _) = lit.node;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
//! Checks for usage of `&Vec[_]` and `&String`.
|
||||
|
||||
use crate::utils::ptr::get_spans;
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{match_qpath, match_type, paths, snippet_opt, span_lint, span_lint_and_then, walk_ptrs_hir_ty};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir::QPath;
|
||||
|
@ -149,7 +148,7 @@ fn check_fn(cx: &LateContext<'_, '_>, decl: &FnDecl, fn_id: HirId, opt_body_id:
|
|||
|
||||
for (idx, (arg, ty)) in decl.inputs.iter().zip(fn_ty.inputs()).enumerate() {
|
||||
if let ty::Ref(_, ty, MutImmutable) = ty.sty {
|
||||
if match_type(cx, ty, &*paths::VEC) {
|
||||
if match_type(cx, ty, &paths::VEC) {
|
||||
let mut ty_snippet = None;
|
||||
if_chain! {
|
||||
if let TyKind::Path(QPath::Resolved(_, ref path)) = walk_ptrs_hir_ty(arg).node;
|
||||
|
@ -164,7 +163,7 @@ fn check_fn(cx: &LateContext<'_, '_>, decl: &FnDecl, fn_id: HirId, opt_body_id:
|
|||
}
|
||||
}
|
||||
};
|
||||
if let Some(spans) = get_spans(cx, opt_body_id, idx, &[(*sym::clone, ".to_owned()")]) {
|
||||
if let Some(spans) = get_spans(cx, opt_body_id, idx, &[("clone", ".to_owned()")]) {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
PTR_ARG,
|
||||
|
@ -193,12 +192,12 @@ fn check_fn(cx: &LateContext<'_, '_>, decl: &FnDecl, fn_id: HirId, opt_body_id:
|
|||
},
|
||||
);
|
||||
}
|
||||
} else if match_type(cx, ty, &*paths::STRING) {
|
||||
} else if match_type(cx, ty, &paths::STRING) {
|
||||
if let Some(spans) = get_spans(
|
||||
cx,
|
||||
opt_body_id,
|
||||
idx,
|
||||
&[(*sym::clone, ".to_string()"), (*sym::as_str, "")],
|
||||
&[("clone", ".to_string()"), ("as_str", "")],
|
||||
) {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
|
@ -220,7 +219,7 @@ fn check_fn(cx: &LateContext<'_, '_>, decl: &FnDecl, fn_id: HirId, opt_body_id:
|
|||
},
|
||||
);
|
||||
}
|
||||
} else if match_type(cx, ty, &*paths::COW) {
|
||||
} else if match_type(cx, ty, &paths::COW) {
|
||||
if_chain! {
|
||||
if let TyKind::Rptr(_, MutTy { ref ty, ..} ) = arg.node;
|
||||
if let TyKind::Path(ref path) = ty.node;
|
||||
|
@ -299,7 +298,7 @@ fn is_null_path(expr: &Expr) -> bool {
|
|||
if let ExprKind::Call(ref pathexp, ref args) = expr.node {
|
||||
if args.is_empty() {
|
||||
if let ExprKind::Path(ref path) = pathexp.node {
|
||||
return match_qpath(path, &*paths::PTR_NULL) || match_qpath(path, &*paths::PTR_NULL_MUT);
|
||||
return match_qpath(path, &paths::PTR_NULL) || match_qpath(path, &paths::PTR_NULL_MUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use crate::utils;
|
||||
use crate::utils::sym;
|
||||
use rustc::hir::{Expr, ExprKind};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_lint_pass, declare_tool_lint};
|
||||
|
@ -93,10 +92,10 @@ fn expr_as_ptr_offset_call<'a, 'tcx>(
|
|||
) -> Option<(&'tcx Expr, &'tcx Expr, Method)> {
|
||||
if let ExprKind::MethodCall(ref path_segment, _, ref args) = expr.node {
|
||||
if is_expr_ty_raw_ptr(cx, &args[0]) {
|
||||
if path_segment.ident.name == *sym::offset {
|
||||
if path_segment.ident.name == sym!(offset) {
|
||||
return Some((&args[0], &args[1], Method::Offset));
|
||||
}
|
||||
if path_segment.ident.name == *sym::wrapping_offset {
|
||||
if path_segment.ident.name == sym!(wrapping_offset) {
|
||||
return Some((&args[0], &args[1], Method::WrappingOffset));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ use syntax::ptr::P;
|
|||
|
||||
use crate::utils::paths::*;
|
||||
use crate::utils::sugg::Sugg;
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{higher, match_def_path, match_type, span_lint_and_then, SpanlessEq};
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -51,7 +50,7 @@ impl QuestionMark {
|
|||
if_chain! {
|
||||
if let Some((if_expr, body, else_)) = higher::if_block(&expr);
|
||||
if let ExprKind::MethodCall(segment, _, args) = &if_expr.node;
|
||||
if segment.ident.name == *sym::is_none;
|
||||
if segment.ident.name == sym!(is_none);
|
||||
if Self::expression_returns_none(cx, body);
|
||||
if let Some(subject) = args.get(0);
|
||||
if Self::is_option(cx, subject);
|
||||
|
@ -104,7 +103,7 @@ impl QuestionMark {
|
|||
fn is_option(cx: &LateContext<'_, '_>, expression: &Expr) -> bool {
|
||||
let expr_ty = cx.tables.expr_ty(expression);
|
||||
|
||||
match_type(cx, expr_ty, &*OPTION)
|
||||
match_type(cx, expr_ty, &OPTION)
|
||||
}
|
||||
|
||||
fn expression_returns_none(cx: &LateContext<'_, '_>, expression: &Expr) -> bool {
|
||||
|
@ -121,7 +120,7 @@ impl QuestionMark {
|
|||
if let Res::Def(DefKind::Ctor(def::CtorOf::Variant, def::CtorKind::Const), def_id) =
|
||||
cx.tables.qpath_res(qp, expression.hir_id)
|
||||
{
|
||||
return match_def_path(cx, def_id, &*OPTION_NONE);
|
||||
return match_def_path(cx, def_id, &OPTION_NONE);
|
||||
}
|
||||
|
||||
false
|
||||
|
|
|
@ -7,7 +7,6 @@ use syntax::ast::RangeLimits;
|
|||
use syntax::source_map::Spanned;
|
||||
|
||||
use crate::utils::sugg::Sugg;
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{get_trait_def_id, higher, implements_trait, SpanlessEq};
|
||||
use crate::utils::{is_integer_literal, paths, snippet, snippet_opt, span_lint, span_lint_and_then};
|
||||
|
||||
|
@ -116,13 +115,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Ranges {
|
|||
if_chain! {
|
||||
// `.iter()` call
|
||||
if let ExprKind::MethodCall(ref iter_path, _, ref iter_args ) = *iter;
|
||||
if iter_path.ident.name == *sym::iter;
|
||||
if iter_path.ident.name == sym!(iter);
|
||||
// range expression in `.zip()` call: `0..x.len()`
|
||||
if let Some(higher::Range { start: Some(start), end: Some(end), .. }) = higher::range(cx, zip_arg);
|
||||
if is_integer_literal(start, 0);
|
||||
// `.len()` call
|
||||
if let ExprKind::MethodCall(ref len_path, _, ref len_args) = end.node;
|
||||
if len_path.ident.name == *sym::len && len_args.len() == 1;
|
||||
if len_path.ident.name == sym!(len) && len_args.len() == 1;
|
||||
// `.iter()` and `.len()` called on same `Path`
|
||||
if let ExprKind::Path(QPath::Resolved(_, ref iter_path)) = iter_args[0].node;
|
||||
if let ExprKind::Path(QPath::Resolved(_, ref len_path)) = len_args[0].node;
|
||||
|
@ -213,7 +212,7 @@ fn has_step_by(cx: &LateContext<'_, '_>, expr: &Expr) -> bool {
|
|||
// can't be called on a borrowed range.
|
||||
let ty = cx.tables.expr_ty_adjusted(expr);
|
||||
|
||||
get_trait_def_id(cx, &*paths::ITERATOR)
|
||||
get_trait_def_id(cx, &paths::ITERATOR)
|
||||
.map_or(false, |iterator_trait| implements_trait(cx, ty, iterator_trait, &[]))
|
||||
}
|
||||
|
||||
|
|
|
@ -94,14 +94,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantClone {
|
|||
|
||||
let (fn_def_id, arg, arg_ty, _) = unwrap_or_continue!(is_call_with_ref_arg(cx, mir, &terminator.kind));
|
||||
|
||||
let from_borrow = match_def_path(cx, fn_def_id, &*paths::CLONE_TRAIT_METHOD)
|
||||
|| match_def_path(cx, fn_def_id, &*paths::TO_OWNED_METHOD)
|
||||
|| (match_def_path(cx, fn_def_id, &*paths::TO_STRING_METHOD)
|
||||
&& match_type(cx, arg_ty, &*paths::STRING));
|
||||
let from_borrow = match_def_path(cx, fn_def_id, &paths::CLONE_TRAIT_METHOD)
|
||||
|| match_def_path(cx, fn_def_id, &paths::TO_OWNED_METHOD)
|
||||
|| (match_def_path(cx, fn_def_id, &paths::TO_STRING_METHOD)
|
||||
&& match_type(cx, arg_ty, &paths::STRING));
|
||||
|
||||
let from_deref = !from_borrow
|
||||
&& (match_def_path(cx, fn_def_id, &*paths::PATH_TO_PATH_BUF)
|
||||
|| match_def_path(cx, fn_def_id, &*paths::OS_STR_TO_OS_STRING));
|
||||
&& (match_def_path(cx, fn_def_id, &paths::PATH_TO_PATH_BUF)
|
||||
|| match_def_path(cx, fn_def_id, &paths::OS_STR_TO_OS_STRING));
|
||||
|
||||
if !from_borrow && !from_deref {
|
||||
continue;
|
||||
|
@ -134,9 +134,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantClone {
|
|||
if let Some((pred_fn_def_id, pred_arg, pred_arg_ty, Some(res))) =
|
||||
is_call_with_ref_arg(cx, mir, &pred_terminator.kind);
|
||||
if *res == mir::Place::Base(mir::PlaceBase::Local(cloned));
|
||||
if match_def_path(cx, pred_fn_def_id, &*paths::DEREF_TRAIT_METHOD);
|
||||
if match_type(cx, pred_arg_ty, &*paths::PATH_BUF)
|
||||
|| match_type(cx, pred_arg_ty, &*paths::OS_STRING);
|
||||
if match_def_path(cx, pred_fn_def_id, &paths::DEREF_TRAIT_METHOD);
|
||||
if match_type(cx, pred_arg_ty, &paths::PATH_BUF)
|
||||
|| match_type(cx, pred_arg_ty, &paths::OS_STRING);
|
||||
then {
|
||||
pred_arg
|
||||
} else {
|
||||
|
|
|
@ -5,7 +5,6 @@ use rustc::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_errors::Applicability;
|
||||
use syntax::ast::LitKind;
|
||||
use syntax::ptr::P;
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Lint for redundant pattern matching over `Result` or
|
||||
|
@ -62,11 +61,11 @@ fn find_sugg_for_if_let<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr,
|
|||
let good_method = match arms[0].pats[0].node {
|
||||
PatKind::TupleStruct(ref path, ref patterns, _) if patterns.len() == 1 => {
|
||||
if let PatKind::Wild = patterns[0].node {
|
||||
if match_qpath(path, &*paths::RESULT_OK) {
|
||||
if match_qpath(path, &paths::RESULT_OK) {
|
||||
"is_ok()"
|
||||
} else if match_qpath(path, &*paths::RESULT_ERR) {
|
||||
} else if match_qpath(path, &paths::RESULT_ERR) {
|
||||
"is_err()"
|
||||
} else if match_qpath(path, &*paths::OPTION_SOME) {
|
||||
} else if match_qpath(path, &paths::OPTION_SOME) {
|
||||
"is_some()"
|
||||
} else {
|
||||
return;
|
||||
|
@ -76,7 +75,7 @@ fn find_sugg_for_if_let<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr,
|
|||
}
|
||||
},
|
||||
|
||||
PatKind::Path(ref path) if match_qpath(path, &*paths::OPTION_NONE) => "is_none()",
|
||||
PatKind::Path(ref path) if match_qpath(path, &paths::OPTION_NONE) => "is_none()",
|
||||
|
||||
_ => return,
|
||||
};
|
||||
|
@ -115,8 +114,8 @@ fn find_sugg_for_match<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, o
|
|||
arms,
|
||||
path_left,
|
||||
path_right,
|
||||
&*paths::RESULT_OK,
|
||||
&*paths::RESULT_ERR,
|
||||
&paths::RESULT_OK,
|
||||
&paths::RESULT_ERR,
|
||||
"is_ok()",
|
||||
"is_err()",
|
||||
)
|
||||
|
@ -133,8 +132,8 @@ fn find_sugg_for_match<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, o
|
|||
arms,
|
||||
path_left,
|
||||
path_right,
|
||||
&*paths::OPTION_SOME,
|
||||
&*paths::OPTION_NONE,
|
||||
&paths::OPTION_SOME,
|
||||
&paths::OPTION_NONE,
|
||||
"is_some()",
|
||||
"is_none()",
|
||||
)
|
||||
|
@ -171,8 +170,8 @@ fn find_good_method_for_match<'a>(
|
|||
arms: &HirVec<Arm>,
|
||||
path_left: &QPath,
|
||||
path_right: &QPath,
|
||||
expected_left: &[Symbol],
|
||||
expected_right: &[Symbol],
|
||||
expected_left: &[&str],
|
||||
expected_right: &[&str],
|
||||
should_be_left: &'a str,
|
||||
should_be_right: &'a str,
|
||||
) -> Option<&'a str> {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use crate::consts::{constant, Constant};
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{is_expn_of, match_def_path, match_type, paths, span_help_and_lint, span_lint};
|
||||
use if_chain::if_chain;
|
||||
use regex_syntax;
|
||||
|
@ -84,8 +83,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Regex {
|
|||
if_chain! {
|
||||
if self.last.is_none();
|
||||
if let Some(ref expr) = block.expr;
|
||||
if match_type(cx, cx.tables.expr_ty(expr), &*paths::REGEX);
|
||||
if let Some(span) = is_expn_of(expr.span, *sym::regex);
|
||||
if match_type(cx, cx.tables.expr_ty(expr), &paths::REGEX);
|
||||
if let Some(span) = is_expn_of(expr.span, "regex");
|
||||
then {
|
||||
if !self.spans.contains(&span) {
|
||||
span_lint(cx,
|
||||
|
@ -113,15 +112,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Regex {
|
|||
if args.len() == 1;
|
||||
if let Some(def_id) = cx.tables.qpath_res(qpath, fun.hir_id).opt_def_id();
|
||||
then {
|
||||
if match_def_path(cx, def_id, &*paths::REGEX_NEW) ||
|
||||
match_def_path(cx, def_id, &*paths::REGEX_BUILDER_NEW) {
|
||||
if match_def_path(cx, def_id, &paths::REGEX_NEW) ||
|
||||
match_def_path(cx, def_id, &paths::REGEX_BUILDER_NEW) {
|
||||
check_regex(cx, &args[0], true);
|
||||
} else if match_def_path(cx, def_id, &*paths::REGEX_BYTES_NEW) ||
|
||||
match_def_path(cx, def_id, &*paths::REGEX_BYTES_BUILDER_NEW) {
|
||||
} else if match_def_path(cx, def_id, &paths::REGEX_BYTES_NEW) ||
|
||||
match_def_path(cx, def_id, &paths::REGEX_BYTES_BUILDER_NEW) {
|
||||
check_regex(cx, &args[0], false);
|
||||
} else if match_def_path(cx, def_id, &*paths::REGEX_SET_NEW) {
|
||||
} else if match_def_path(cx, def_id, &paths::REGEX_SET_NEW) {
|
||||
check_set(cx, &args[0], true);
|
||||
} else if match_def_path(cx, def_id, &*paths::REGEX_BYTES_SET_NEW) {
|
||||
} else if match_def_path(cx, def_id, &paths::REGEX_BYTES_SET_NEW) {
|
||||
check_set(cx, &args[0], false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
use crate::utils::sym;
|
||||
use crate::utils::{match_def_path, span_lint_and_sugg};
|
||||
use if_chain::if_chain;
|
||||
use lazy_static::lazy_static;
|
||||
use rustc::hir;
|
||||
use rustc::hir::def::{DefKind, Res};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_errors::Applicability;
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of `ATOMIC_X_INIT`, `ONCE_INIT`, and
|
||||
|
@ -59,35 +56,33 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ReplaceConsts {
|
|||
}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref REPLACEMENTS: [([Symbol; 3], &'static str); 25] = [
|
||||
const REPLACEMENTS: [([&str; 3], &'static str); 25] = [
|
||||
// Once
|
||||
([*sym::core, *sym::sync, *sym::ONCE_INIT], "Once::new()"),
|
||||
(["core", "sync", "ONCE_INIT"], "Once::new()"),
|
||||
// Min
|
||||
([*sym::core, *sym::isize, *sym::MIN], "isize::min_value()"),
|
||||
([*sym::core, *sym::i8, *sym::MIN], "i8::min_value()"),
|
||||
([*sym::core, *sym::i16, *sym::MIN], "i16::min_value()"),
|
||||
([*sym::core, *sym::i32, *sym::MIN], "i32::min_value()"),
|
||||
([*sym::core, *sym::i64, *sym::MIN], "i64::min_value()"),
|
||||
([*sym::core, *sym::i128, *sym::MIN], "i128::min_value()"),
|
||||
([*sym::core, *sym::usize, *sym::MIN], "usize::min_value()"),
|
||||
([*sym::core, *sym::u8, *sym::MIN], "u8::min_value()"),
|
||||
([*sym::core, *sym::u16, *sym::MIN], "u16::min_value()"),
|
||||
([*sym::core, *sym::u32, *sym::MIN], "u32::min_value()"),
|
||||
([*sym::core, *sym::u64, *sym::MIN], "u64::min_value()"),
|
||||
([*sym::core, *sym::u128, *sym::MIN], "u128::min_value()"),
|
||||
(["core", "isize", "MIN"], "isize::min_value()"),
|
||||
(["core", "i8", "MIN"], "i8::min_value()"),
|
||||
(["core", "i16", "MIN"], "i16::min_value()"),
|
||||
(["core", "i32", "MIN"], "i32::min_value()"),
|
||||
(["core", "i64", "MIN"], "i64::min_value()"),
|
||||
(["core", "i128", "MIN"], "i128::min_value()"),
|
||||
(["core", "usize", "MIN"], "usize::min_value()"),
|
||||
(["core", "u8", "MIN"], "u8::min_value()"),
|
||||
(["core", "u16", "MIN"], "u16::min_value()"),
|
||||
(["core", "u32", "MIN"], "u32::min_value()"),
|
||||
(["core", "u64", "MIN"], "u64::min_value()"),
|
||||
(["core", "u128", "MIN"], "u128::min_value()"),
|
||||
// Max
|
||||
([*sym::core, *sym::isize, *sym::MAX], "isize::max_value()"),
|
||||
([*sym::core, *sym::i8, *sym::MAX], "i8::max_value()"),
|
||||
([*sym::core, *sym::i16, *sym::MAX], "i16::max_value()"),
|
||||
([*sym::core, *sym::i32, *sym::MAX], "i32::max_value()"),
|
||||
([*sym::core, *sym::i64, *sym::MAX], "i64::max_value()"),
|
||||
([*sym::core, *sym::i128, *sym::MAX], "i128::max_value()"),
|
||||
([*sym::core, *sym::usize, *sym::MAX], "usize::max_value()"),
|
||||
([*sym::core, *sym::u8, *sym::MAX], "u8::max_value()"),
|
||||
([*sym::core, *sym::u16, *sym::MAX], "u16::max_value()"),
|
||||
([*sym::core, *sym::u32, *sym::MAX], "u32::max_value()"),
|
||||
([*sym::core, *sym::u64, *sym::MAX], "u64::max_value()"),
|
||||
([*sym::core, *sym::u128, *sym::MAX], "u128::max_value()"),
|
||||
(["core", "isize", "MAX"], "isize::max_value()"),
|
||||
(["core", "i8", "MAX"], "i8::max_value()"),
|
||||
(["core", "i16", "MAX"], "i16::max_value()"),
|
||||
(["core", "i32", "MAX"], "i32::max_value()"),
|
||||
(["core", "i64", "MAX"], "i64::max_value()"),
|
||||
(["core", "i128", "MAX"], "i128::max_value()"),
|
||||
(["core", "usize", "MAX"], "usize::max_value()"),
|
||||
(["core", "u8", "MAX"], "u8::max_value()"),
|
||||
(["core", "u16", "MAX"], "u16::max_value()"),
|
||||
(["core", "u32", "MAX"], "u32::max_value()"),
|
||||
(["core", "u64", "MAX"], "u64::max_value()"),
|
||||
(["core", "u128", "MAX"], "u128::max_value()"),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ use syntax::source_map::Span;
|
|||
use syntax::visit::FnKind;
|
||||
use syntax_pos::BytePos;
|
||||
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{in_macro_or_desugar, match_path_ast, snippet_opt, span_lint_and_then, span_note_and_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -162,7 +161,7 @@ impl Return {
|
|||
if let Some(ref initexpr) = local.init;
|
||||
if let ast::PatKind::Ident(_, ident, _) = local.pat.node;
|
||||
if let ast::ExprKind::Path(_, ref path) = retexpr.node;
|
||||
if match_path_ast(path, &[ident.name]);
|
||||
if match_path_ast(path, &[&*ident.name.as_str()]);
|
||||
if !in_external_macro(cx.sess(), initexpr.span);
|
||||
then {
|
||||
span_note_and_lint(cx,
|
||||
|
@ -253,7 +252,7 @@ impl EarlyLintPass for Return {
|
|||
}
|
||||
|
||||
fn attr_is_cfg(attr: &ast::Attribute) -> bool {
|
||||
attr.meta_item_list().is_some() && attr.check_name(*sym::cfg)
|
||||
attr.meta_item_list().is_some() && attr.check_name(sym!(cfg))
|
||||
}
|
||||
|
||||
// get the def site
|
||||
|
|
|
@ -24,7 +24,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SerdeAPI {
|
|||
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
|
||||
if let ItemKind::Impl(_, _, _, _, Some(ref trait_ref), _, ref items) = item.node {
|
||||
let did = trait_ref.path.res.def_id();
|
||||
if let Some(visit_did) = get_trait_def_id(cx, &*paths::SERDE_DE_VISITOR) {
|
||||
if let Some(visit_did) = get_trait_def_id(cx, &paths::SERDE_DE_VISITOR) {
|
||||
if did == visit_did {
|
||||
let mut seen_str = None;
|
||||
let mut seen_string = None;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use crate::utils::sugg::Sugg;
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{get_enclosing_block, match_qpath, span_lint_and_then, SpanlessEq};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir::intravisit::{walk_block, walk_expr, walk_stmt, NestedVisitorMap, Visitor};
|
||||
|
@ -110,7 +109,7 @@ impl SlowVectorInit {
|
|||
if_chain! {
|
||||
if let ExprKind::Call(ref func, ref args) = expr.node;
|
||||
if let ExprKind::Path(ref path) = func.node;
|
||||
if match_qpath(path, &[*sym::Vec, *sym::with_capacity]);
|
||||
if match_qpath(path, &["Vec", "with_capacity"]);
|
||||
if args.len() == 1;
|
||||
|
||||
then {
|
||||
|
@ -201,8 +200,8 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
|
|||
if self.initialization_found;
|
||||
if let ExprKind::MethodCall(ref path, _, ref args) = expr.node;
|
||||
if let ExprKind::Path(ref qpath_subj) = args[0].node;
|
||||
if match_qpath(&qpath_subj, &[self.vec_alloc.variable_name]);
|
||||
if path.ident.name == *sym::extend;
|
||||
if match_qpath(&qpath_subj, &[&*self.vec_alloc.variable_name.as_str()]);
|
||||
if path.ident.name == sym!(extend);
|
||||
if let Some(ref extend_arg) = args.get(1);
|
||||
if self.is_repeat_take(extend_arg);
|
||||
|
||||
|
@ -218,8 +217,8 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
|
|||
if self.initialization_found;
|
||||
if let ExprKind::MethodCall(ref path, _, ref args) = expr.node;
|
||||
if let ExprKind::Path(ref qpath_subj) = args[0].node;
|
||||
if match_qpath(&qpath_subj, &[self.vec_alloc.variable_name]);
|
||||
if path.ident.name == *sym::resize;
|
||||
if match_qpath(&qpath_subj, &[&*self.vec_alloc.variable_name.as_str()]);
|
||||
if path.ident.name == sym!(resize);
|
||||
if let (Some(ref len_arg), Some(fill_arg)) = (args.get(1), args.get(2));
|
||||
|
||||
// Check that is filled with 0
|
||||
|
@ -239,7 +238,7 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
|
|||
fn is_repeat_take(&self, expr: &Expr) -> bool {
|
||||
if_chain! {
|
||||
if let ExprKind::MethodCall(ref take_path, _, ref take_args) = expr.node;
|
||||
if take_path.ident.name == *sym::take;
|
||||
if take_path.ident.name == sym!(take);
|
||||
|
||||
// Check that take is applied to `repeat(0)`
|
||||
if let Some(ref repeat_expr) = take_args.get(0);
|
||||
|
@ -262,7 +261,7 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
|
|||
if_chain! {
|
||||
if let ExprKind::Call(ref fn_expr, ref repeat_args) = expr.node;
|
||||
if let ExprKind::Path(ref qpath_repeat) = fn_expr.node;
|
||||
if match_qpath(&qpath_repeat, &[*sym::repeat]);
|
||||
if match_qpath(&qpath_repeat, &["repeat"]);
|
||||
if let Some(ref repeat_arg) = repeat_args.get(0);
|
||||
if let ExprKind::Lit(ref lit) = repeat_arg.node;
|
||||
if let LitKind::Int(0, _) = lit.node;
|
||||
|
|
|
@ -4,7 +4,6 @@ use rustc::{declare_lint_pass, declare_tool_lint};
|
|||
use rustc_errors::Applicability;
|
||||
use syntax::source_map::Spanned;
|
||||
|
||||
use crate::utils::sym;
|
||||
use crate::utils::SpanlessEq;
|
||||
use crate::utils::{get_parent_expr, is_allowed, match_type, paths, span_lint, span_lint_and_sugg, walk_ptrs_ty};
|
||||
|
||||
|
@ -120,7 +119,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd {
|
|||
}
|
||||
|
||||
fn is_string(cx: &LateContext<'_, '_>, e: &Expr) -> bool {
|
||||
match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(e)), &*paths::STRING)
|
||||
match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(e)), &paths::STRING)
|
||||
}
|
||||
|
||||
fn is_add(cx: &LateContext<'_, '_>, src: &Expr, target: &Expr) -> bool {
|
||||
|
@ -147,7 +146,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes {
|
|||
use syntax::ast::{LitKind, StrStyle};
|
||||
|
||||
if let ExprKind::MethodCall(ref path, _, ref args) = e.node {
|
||||
if path.ident.name == *sym::as_bytes {
|
||||
if path.ident.name == sym!(as_bytes) {
|
||||
if let ExprKind::Lit(ref lit) = args[0].node {
|
||||
if let LitKind::Str(ref lit_content, style) = lit.node {
|
||||
let callsite = snippet(cx, args[0].span.source_callsite(), r#""foo""#);
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
use crate::utils::sym;
|
||||
use crate::utils::{get_trait_def_id, span_lint, trait_ref_of_method};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir;
|
||||
use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_lint_pass, declare_tool_lint};
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Lints for suspicious operations in impls of arithmetic operators, e.g.
|
||||
|
@ -91,7 +89,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SuspiciousImpl {
|
|||
cx,
|
||||
expr,
|
||||
binop.node,
|
||||
&[*sym::Add, *sym::Sub, *sym::Mul, *sym::Div],
|
||||
&["Add", "Sub", "Mul", "Div"],
|
||||
&[
|
||||
hir::BinOpKind::Add,
|
||||
hir::BinOpKind::Sub,
|
||||
|
@ -112,16 +110,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for SuspiciousImpl {
|
|||
expr,
|
||||
binop.node,
|
||||
&[
|
||||
*sym::AddAssign,
|
||||
*sym::SubAssign,
|
||||
*sym::MulAssign,
|
||||
*sym::DivAssign,
|
||||
*sym::BitAndAssign,
|
||||
*sym::BitOrAssign,
|
||||
*sym::BitXorAssign,
|
||||
*sym::RemAssign,
|
||||
*sym::ShlAssign,
|
||||
*sym::ShrAssign,
|
||||
"AddAssign",
|
||||
"SubAssign",
|
||||
"MulAssign",
|
||||
"DivAssign",
|
||||
"BitAndAssign",
|
||||
"BitOrAssign",
|
||||
"BitXorAssign",
|
||||
"RemAssign",
|
||||
"ShlAssign",
|
||||
"ShrAssign",
|
||||
],
|
||||
&[
|
||||
hir::BinOpKind::Add,
|
||||
|
@ -151,11 +149,11 @@ fn check_binop(
|
|||
cx: &LateContext<'_, '_>,
|
||||
expr: &hir::Expr,
|
||||
binop: hir::BinOpKind,
|
||||
traits: &[Symbol],
|
||||
traits: &[&'static str],
|
||||
expected_ops: &[hir::BinOpKind],
|
||||
) -> Option<Symbol> {
|
||||
) -> Option<&'static str> {
|
||||
let mut trait_ids = vec![];
|
||||
let [krate, module] = *crate::utils::paths::OPS_MODULE;
|
||||
let [krate, module] = crate::utils::paths::OPS_MODULE;
|
||||
|
||||
for &t in traits {
|
||||
let path = [krate, module, t];
|
||||
|
|
|
@ -96,8 +96,8 @@ fn check_manual_swap(cx: &LateContext<'_, '_>, block: &Block) {
|
|||
|
||||
if matches!(ty.sty, ty::Slice(_)) ||
|
||||
matches!(ty.sty, ty::Array(_, _)) ||
|
||||
match_type(cx, ty, &*paths::VEC) ||
|
||||
match_type(cx, ty, &*paths::VEC_DEQUE) {
|
||||
match_type(cx, ty, &paths::VEC) ||
|
||||
match_type(cx, ty, &paths::VEC_DEQUE) {
|
||||
return Some((lhs1, idx1, idx2));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -221,7 +221,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute {
|
|||
if let ExprKind::Call(ref path_expr, ref args) = e.node {
|
||||
if let ExprKind::Path(ref qpath) = path_expr.node {
|
||||
if let Some(def_id) = cx.tables.qpath_res(qpath, path_expr.hir_id).opt_def_id() {
|
||||
if match_def_path(cx, def_id, &*paths::TRANSMUTE) {
|
||||
if match_def_path(cx, def_id, &paths::TRANSMUTE) {
|
||||
let from_ty = cx.tables.expr_ty(&args[0]);
|
||||
let to_ty = cx.tables.expr_ty(e);
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TransmutingNull {
|
|||
if_chain! {
|
||||
if let ExprKind::Call(ref func, ref args) = expr.node;
|
||||
if let ExprKind::Path(ref path) = func.node;
|
||||
if match_qpath(path, &*paths::STD_MEM_TRANSMUTE);
|
||||
if match_qpath(path, &paths::STD_MEM_TRANSMUTE);
|
||||
if args.len() == 1;
|
||||
|
||||
then {
|
||||
|
@ -79,7 +79,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TransmutingNull {
|
|||
if_chain! {
|
||||
if let ExprKind::Call(ref func1, ref args1) = args[0].node;
|
||||
if let ExprKind::Path(ref path1) = func1.node;
|
||||
if match_qpath(path1, &*paths::STD_PTR_NULL);
|
||||
if match_qpath(path1, &paths::STD_PTR_NULL);
|
||||
if args1.len() == 0;
|
||||
then {
|
||||
span_lint(
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::cmp;
|
||||
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{in_macro_or_desugar, is_copy, is_self_ty, snippet, span_lint_and_sugg};
|
||||
use if_chain::if_chain;
|
||||
use matches::matches;
|
||||
|
@ -169,7 +168,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TriviallyCopyPassByRef {
|
|||
return;
|
||||
}
|
||||
for a in attrs {
|
||||
if a.meta_item_list().is_some() && a.check_name(*sym::proc_macro_derive) {
|
||||
if a.meta_item_list().is_some() && a.check_name(sym!(proc_macro_derive)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,11 +18,9 @@ use rustc_typeck::hir_ty_to_ty;
|
|||
use syntax::ast::{FloatTy, IntTy, UintTy};
|
||||
use syntax::errors::DiagnosticBuilder;
|
||||
use syntax::source_map::Span;
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
use crate::consts::{constant, Constant};
|
||||
use crate::utils::paths;
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{
|
||||
clip, comparisons, differing_macro_contexts, higher, in_constant, in_macro_or_desugar, int_bits, last_path_segment,
|
||||
match_def_path, match_path, multispan_sugg, same_tys, sext, snippet, snippet_opt, snippet_with_applicability,
|
||||
|
@ -208,7 +206,7 @@ fn check_fn_decl(cx: &LateContext<'_, '_>, decl: &FnDecl) {
|
|||
}
|
||||
|
||||
/// Checks if `qpath` has last segment with type parameter matching `path`
|
||||
fn match_type_parameter(cx: &LateContext<'_, '_>, qpath: &QPath, path: &[Symbol]) -> bool {
|
||||
fn match_type_parameter(cx: &LateContext<'_, '_>, qpath: &QPath, path: &[&str]) -> bool {
|
||||
let last = last_path_segment(qpath);
|
||||
if_chain! {
|
||||
if let Some(ref params) = last.args;
|
||||
|
@ -243,7 +241,7 @@ fn check_ty(cx: &LateContext<'_, '_>, hir_ty: &hir::Ty, is_local: bool) {
|
|||
let res = cx.tables.qpath_res(qpath, hir_id);
|
||||
if let Some(def_id) = res.opt_def_id() {
|
||||
if Some(def_id) == cx.tcx.lang_items().owned_box() {
|
||||
if match_type_parameter(cx, qpath, &*paths::VEC) {
|
||||
if match_type_parameter(cx, qpath, &paths::VEC) {
|
||||
span_help_and_lint(
|
||||
cx,
|
||||
BOX_VEC,
|
||||
|
@ -253,7 +251,7 @@ fn check_ty(cx: &LateContext<'_, '_>, hir_ty: &hir::Ty, is_local: bool) {
|
|||
);
|
||||
return; // don't recurse into the type
|
||||
}
|
||||
} else if match_def_path(cx, def_id, &*paths::VEC) {
|
||||
} else if match_def_path(cx, def_id, &paths::VEC) {
|
||||
if_chain! {
|
||||
// Get the _ part of Vec<_>
|
||||
if let Some(ref last) = last_path_segment(qpath).args;
|
||||
|
@ -288,8 +286,8 @@ fn check_ty(cx: &LateContext<'_, '_>, hir_ty: &hir::Ty, is_local: bool) {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if match_def_path(cx, def_id, &*paths::OPTION) {
|
||||
if match_type_parameter(cx, qpath, &*paths::OPTION) {
|
||||
} else if match_def_path(cx, def_id, &paths::OPTION) {
|
||||
if match_type_parameter(cx, qpath, &paths::OPTION) {
|
||||
span_lint(
|
||||
cx,
|
||||
OPTION_OPTION,
|
||||
|
@ -299,7 +297,7 @@ fn check_ty(cx: &LateContext<'_, '_>, hir_ty: &hir::Ty, is_local: bool) {
|
|||
);
|
||||
return; // don't recurse into the type
|
||||
}
|
||||
} else if match_def_path(cx, def_id, &*paths::LINKED_LIST) {
|
||||
} else if match_def_path(cx, def_id, &paths::LINKED_LIST) {
|
||||
span_help_and_lint(
|
||||
cx,
|
||||
LINKEDLIST,
|
||||
|
@ -428,7 +426,7 @@ fn is_any_trait(t: &hir::Ty) -> bool {
|
|||
if traits.len() >= 1;
|
||||
// Only Send/Sync can be used as additional traits, so it is enough to
|
||||
// check only the first trait.
|
||||
if match_path(&traits[0].trait_ref.path, &*paths::ANY_TRAIT);
|
||||
if match_path(&traits[0].trait_ref.path, &paths::ANY_TRAIT);
|
||||
then {
|
||||
return true;
|
||||
}
|
||||
|
@ -2089,14 +2087,14 @@ impl<'tcx> ImplicitHasherType<'tcx> {
|
|||
|
||||
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
|
||||
|
||||
if match_path(path, &*paths::HASHMAP) && params_len == 2 {
|
||||
if match_path(path, &paths::HASHMAP) && params_len == 2 {
|
||||
Some(ImplicitHasherType::HashMap(
|
||||
hir_ty.span,
|
||||
ty,
|
||||
snippet(cx, params[0].span, "K"),
|
||||
snippet(cx, params[1].span, "V"),
|
||||
))
|
||||
} else if match_path(path, &*paths::HASHSET) && params_len == 1 {
|
||||
} else if match_path(path, &paths::HASHSET) && params_len == 1 {
|
||||
Some(ImplicitHasherType::HashSet(
|
||||
hir_ty.span,
|
||||
ty,
|
||||
|
@ -2199,11 +2197,11 @@ impl<'a, 'b, 'tcx: 'a + 'b> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'
|
|||
return;
|
||||
}
|
||||
|
||||
if match_path(ty_path, &*paths::HASHMAP) {
|
||||
if method.ident.name == *sym::new {
|
||||
if match_path(ty_path, &paths::HASHMAP) {
|
||||
if method.ident.name == sym!(new) {
|
||||
self.suggestions
|
||||
.insert(e.span, "HashMap::default()".to_string());
|
||||
} else if method.ident.name == *sym::with_capacity {
|
||||
} else if method.ident.name == sym!(with_capacity) {
|
||||
self.suggestions.insert(
|
||||
e.span,
|
||||
format!(
|
||||
|
@ -2212,11 +2210,11 @@ impl<'a, 'b, 'tcx: 'a + 'b> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'
|
|||
),
|
||||
);
|
||||
}
|
||||
} else if match_path(ty_path, &*paths::HASHSET) {
|
||||
if method.ident.name == *sym::new {
|
||||
} else if match_path(ty_path, &paths::HASHSET) {
|
||||
if method.ident.name == sym!(new) {
|
||||
self.suggestions
|
||||
.insert(e.span, "HashSet::default()".to_string());
|
||||
} else if method.ident.name == *sym::with_capacity {
|
||||
} else if method.ident.name == sym!(with_capacity) {
|
||||
self.suggestions.insert(
|
||||
e.span,
|
||||
format!(
|
||||
|
|
|
@ -43,7 +43,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedIoAmount {
|
|||
hir::ExprKind::Match(ref res, _, _) if is_try(expr).is_some() => {
|
||||
if let hir::ExprKind::Call(ref func, ref args) = res.node {
|
||||
if let hir::ExprKind::Path(ref path) = func.node {
|
||||
if match_qpath(path, &*paths::TRY_INTO_RESULT) && args.len() == 1 {
|
||||
if match_qpath(path, &paths::TRY_INTO_RESULT) && args.len() == 1 {
|
||||
check_method_call(cx, &args[0], expr);
|
||||
}
|
||||
}
|
||||
|
@ -67,14 +67,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedIoAmount {
|
|||
fn check_method_call(cx: &LateContext<'_, '_>, call: &hir::Expr, expr: &hir::Expr) {
|
||||
if let hir::ExprKind::MethodCall(ref path, _, _) = call.node {
|
||||
let symbol = &*path.ident.as_str();
|
||||
if match_trait_method(cx, call, &*paths::IO_READ) && symbol == "read" {
|
||||
if match_trait_method(cx, call, &paths::IO_READ) && symbol == "read" {
|
||||
span_lint(
|
||||
cx,
|
||||
UNUSED_IO_AMOUNT,
|
||||
expr.span,
|
||||
"handle read amount returned or use `Read::read_exact` instead",
|
||||
);
|
||||
} else if match_trait_method(cx, call, &*paths::IO_WRITE) && symbol == "write" {
|
||||
} else if match_trait_method(cx, call, &paths::IO_WRITE) && symbol == "write" {
|
||||
span_lint(
|
||||
cx,
|
||||
UNUSED_IO_AMOUNT,
|
||||
|
|
|
@ -2,7 +2,6 @@ use if_chain::if_chain;
|
|||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{
|
||||
higher::if_block, in_macro_or_desugar, match_type, paths, span_lint_and_then, usage::is_potentially_mutated,
|
||||
};
|
||||
|
@ -96,7 +95,7 @@ fn collect_unwrap_info<'a, 'tcx: 'a>(
|
|||
if let ExprKind::MethodCall(method_name, _, args) = &expr.node;
|
||||
if let ExprKind::Path(QPath::Resolved(None, path)) = &args[0].node;
|
||||
let ty = cx.tables.expr_ty(&args[0]);
|
||||
if match_type(cx, ty, &*paths::OPTION) || match_type(cx, ty, &*paths::RESULT);
|
||||
if match_type(cx, ty, &paths::OPTION) || match_type(cx, ty, &paths::RESULT);
|
||||
let name = method_name.ident.as_str();
|
||||
if ["is_some", "is_none", "is_ok", "is_err"].contains(&&*name);
|
||||
then {
|
||||
|
@ -144,8 +143,8 @@ impl<'a, 'tcx: 'a> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> {
|
|||
if_chain! {
|
||||
if let ExprKind::MethodCall(ref method_name, _, ref args) = expr.node;
|
||||
if let ExprKind::Path(QPath::Resolved(None, ref path)) = args[0].node;
|
||||
if [*sym::unwrap, *sym::unwrap_err].contains(&method_name.ident.name);
|
||||
let call_to_unwrap = method_name.ident.name == *sym::unwrap;
|
||||
if [sym!(unwrap), sym!(unwrap_err)].contains(&method_name.ident.name);
|
||||
let call_to_unwrap = method_name.ident.name == sym!(unwrap);
|
||||
if let Some(unwrappable) = self.unwrappables.iter()
|
||||
.find(|u| u.ident.res == path.res);
|
||||
then {
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#![deny(clippy::missing_docs_in_private_items)]
|
||||
|
||||
use crate::utils::sym;
|
||||
use lazy_static::lazy_static;
|
||||
use std::default::Default;
|
||||
use std::io::Read;
|
||||
|
@ -14,7 +13,7 @@ use toml;
|
|||
/// Gets the configuration file from arguments.
|
||||
pub fn file_from_args(args: &[ast::NestedMetaItem]) -> Result<Option<path::PathBuf>, (&'static str, source_map::Span)> {
|
||||
for arg in args.iter().filter_map(syntax::ast::NestedMetaItem::meta_item) {
|
||||
if arg.check_name(*sym::conf_file) {
|
||||
if arg.check_name(sym!(conf_file)) {
|
||||
return match arg.node {
|
||||
ast::MetaItemKind::Word | ast::MetaItemKind::List(_) => {
|
||||
Err(("`conf_file` must be a named value", arg.span))
|
||||
|
|
|
@ -3,13 +3,11 @@
|
|||
|
||||
#![deny(clippy::missing_docs_in_private_items)]
|
||||
|
||||
use crate::utils::sym;
|
||||
use crate::utils::{is_expn_of, match_def_path, match_qpath, paths, resolve_node};
|
||||
use if_chain::if_chain;
|
||||
use rustc::lint::LateContext;
|
||||
use rustc::{hir, ty};
|
||||
use syntax::ast;
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
/// Converts a hir binary operator to the corresponding `ast` type.
|
||||
pub fn binop(op: hir::BinOpKind) -> ast::BinOpKind {
|
||||
|
@ -50,8 +48,8 @@ pub struct Range<'a> {
|
|||
pub fn range<'a, 'b, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'b hir::Expr) -> Option<Range<'b>> {
|
||||
/// Finds the field named `name` in the field. Always return `Some` for
|
||||
/// convenience.
|
||||
fn get_field(name: Symbol, fields: &[hir::Field]) -> Option<&hir::Expr> {
|
||||
let expr = &fields.iter().find(|field| field.ident.name == name)?.expr;
|
||||
fn get_field<'c>(name: &str, fields: &'c [hir::Field]) -> Option<&'c hir::Expr> {
|
||||
let expr = &fields.iter().find(|field| field.ident.name.as_str() == name)?.expr;
|
||||
|
||||
Some(expr)
|
||||
}
|
||||
|
@ -90,7 +88,7 @@ pub fn range<'a, 'b, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'b hir::Expr) -> O
|
|||
|
||||
match expr.node {
|
||||
hir::ExprKind::Path(ref path) => {
|
||||
if match_qpath(path, &*paths::RANGE_FULL_STD) || match_qpath(path, &*paths::RANGE_FULL) {
|
||||
if match_qpath(path, &paths::RANGE_FULL_STD) || match_qpath(path, &paths::RANGE_FULL) {
|
||||
Some(Range {
|
||||
start: None,
|
||||
end: None,
|
||||
|
@ -102,8 +100,8 @@ pub fn range<'a, 'b, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'b hir::Expr) -> O
|
|||
},
|
||||
hir::ExprKind::Call(ref path, ref args) => {
|
||||
if let hir::ExprKind::Path(ref path) = path.node {
|
||||
if match_qpath(path, &*paths::RANGE_INCLUSIVE_STD_NEW)
|
||||
|| match_qpath(path, &*paths::RANGE_INCLUSIVE_NEW)
|
||||
if match_qpath(path, &paths::RANGE_INCLUSIVE_STD_NEW)
|
||||
|| match_qpath(path, &paths::RANGE_INCLUSIVE_NEW)
|
||||
{
|
||||
Some(Range {
|
||||
start: Some(&args[0]),
|
||||
|
@ -118,30 +116,30 @@ pub fn range<'a, 'b, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'b hir::Expr) -> O
|
|||
}
|
||||
},
|
||||
hir::ExprKind::Struct(ref path, ref fields, None) => {
|
||||
if match_qpath(path, &*paths::RANGE_FROM_STD) || match_qpath(path, &*paths::RANGE_FROM) {
|
||||
if match_qpath(path, &paths::RANGE_FROM_STD) || match_qpath(path, &paths::RANGE_FROM) {
|
||||
Some(Range {
|
||||
start: Some(get_field(*sym::start, fields)?),
|
||||
start: Some(get_field("start", fields)?),
|
||||
end: None,
|
||||
limits: ast::RangeLimits::HalfOpen,
|
||||
})
|
||||
} else if match_qpath(path, &*paths::RANGE_STD) || match_qpath(path, &*paths::RANGE) {
|
||||
} else if match_qpath(path, &paths::RANGE_STD) || match_qpath(path, &paths::RANGE) {
|
||||
Some(Range {
|
||||
start: Some(get_field(*sym::start, fields)?),
|
||||
end: Some(get_field(*sym::end, fields)?),
|
||||
start: Some(get_field("start", fields)?),
|
||||
end: Some(get_field("end", fields)?),
|
||||
limits: ast::RangeLimits::HalfOpen,
|
||||
})
|
||||
} else if match_qpath(path, &*paths::RANGE_TO_INCLUSIVE_STD)
|
||||
|| match_qpath(path, &*paths::RANGE_TO_INCLUSIVE)
|
||||
} else if match_qpath(path, &paths::RANGE_TO_INCLUSIVE_STD)
|
||||
|| match_qpath(path, &paths::RANGE_TO_INCLUSIVE)
|
||||
{
|
||||
Some(Range {
|
||||
start: None,
|
||||
end: Some(get_field(*sym::end, fields)?),
|
||||
end: Some(get_field("end", fields)?),
|
||||
limits: ast::RangeLimits::Closed,
|
||||
})
|
||||
} else if match_qpath(path, &*paths::RANGE_TO_STD) || match_qpath(path, &*paths::RANGE_TO) {
|
||||
} else if match_qpath(path, &paths::RANGE_TO_STD) || match_qpath(path, &paths::RANGE_TO) {
|
||||
Some(Range {
|
||||
start: None,
|
||||
end: Some(get_field(*sym::end, fields)?),
|
||||
end: Some(get_field("end", fields)?),
|
||||
limits: ast::RangeLimits::HalfOpen,
|
||||
})
|
||||
} else {
|
||||
|
@ -238,14 +236,14 @@ pub fn vec_macro<'e>(cx: &LateContext<'_, '_>, expr: &'e hir::Expr) -> Option<Ve
|
|||
if_chain! {
|
||||
if let hir::ExprKind::Call(ref fun, ref args) = expr.node;
|
||||
if let hir::ExprKind::Path(ref path) = fun.node;
|
||||
if is_expn_of(fun.span, *sym::vec).is_some();
|
||||
if is_expn_of(fun.span, "vec").is_some();
|
||||
if let Some(fun_def_id) = resolve_node(cx, path, fun.hir_id).opt_def_id();
|
||||
then {
|
||||
return if match_def_path(cx, fun_def_id, &*paths::VEC_FROM_ELEM) && args.len() == 2 {
|
||||
return if match_def_path(cx, fun_def_id, &paths::VEC_FROM_ELEM) && args.len() == 2 {
|
||||
// `vec![elem; size]` case
|
||||
Some(VecArgs::Repeat(&args[0], &args[1]))
|
||||
}
|
||||
else if match_def_path(cx, fun_def_id, &*paths::SLICE_INTO_VEC) && args.len() == 1 {
|
||||
else if match_def_path(cx, fun_def_id, &paths::SLICE_INTO_VEC) && args.len() == 1 {
|
||||
// `vec![a, b, c]` case
|
||||
if_chain! {
|
||||
if let hir::ExprKind::Box(ref boxed) = args[0].node;
|
||||
|
|
|
@ -77,9 +77,9 @@ impl EarlyLintPass for ClippyLintsInternal {
|
|||
fn check_crate(&mut self, _cx: &EarlyContext<'_>, _krate: &AstCrate) {
|
||||
/*
|
||||
FIXME: turn back on when we get rid of all the lazy_statics
|
||||
if let Some(utils) = krate.module.items.iter().find(|item| item.ident.name == *sym::utils) {
|
||||
if let Some(utils) = krate.module.items.iter().find(|item| item.ident.name == sym!(utils)) {
|
||||
if let ItemKind::Mod(ref utils_mod) = utils.node {
|
||||
if let Some(paths) = utils_mod.items.iter().find(|item| item.ident.name == *sym::paths) {
|
||||
if let Some(paths) = utils_mod.items.iter().find(|item| item.ident.name == sym!(paths)) {
|
||||
if let ItemKind::Mod(ref paths_mod) = paths.node {
|
||||
let mut last_name: Option<LocalInternedString> = None;
|
||||
for item in &*paths_mod.items {
|
||||
|
@ -123,7 +123,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass {
|
|||
if_chain! {
|
||||
if let hir::TraitRef{path, ..} = trait_ref;
|
||||
if let Res::Def(DefKind::Trait, def_id) = path.res;
|
||||
if match_def_path(cx, def_id, &*paths::LINT_PASS);
|
||||
if match_def_path(cx, def_id, &paths::LINT_PASS);
|
||||
then {
|
||||
let mut collector = LintCollector {
|
||||
output: &mut self.registered_lints,
|
||||
|
@ -181,7 +181,7 @@ fn is_lint_ref_type<'tcx>(cx: &LateContext<'_, 'tcx>, ty: &Ty) -> bool {
|
|||
{
|
||||
if let TyKind::Path(ref path) = inner.node {
|
||||
if let Res::Def(DefKind::Struct, def_id) = cx.tables.qpath_res(path, inner.hir_id) {
|
||||
return match_def_path(cx, def_id, &*paths::LINT);
|
||||
return match_def_path(cx, def_id, &paths::LINT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -235,8 +235,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CompilerLintFunctions {
|
|||
let fn_name = path.ident.as_str().to_string();
|
||||
if let Some(sugg) = self.map.get(&fn_name);
|
||||
let ty = walk_ptrs_ty(cx.tables.expr_ty(&args[0]));
|
||||
if match_type(cx, ty, &*paths::EARLY_CONTEXT)
|
||||
|| match_type(cx, ty, &*paths::LATE_CONTEXT);
|
||||
if match_type(cx, ty, &paths::EARLY_CONTEXT)
|
||||
|| match_type(cx, ty, &paths::LATE_CONTEXT);
|
||||
then {
|
||||
span_help_and_lint(
|
||||
cx,
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#[macro_use]
|
||||
pub mod sym;
|
||||
|
||||
pub mod attrs;
|
||||
pub mod author;
|
||||
pub mod camel_case;
|
||||
|
@ -12,7 +15,6 @@ pub mod internal_lints;
|
|||
pub mod paths;
|
||||
pub mod ptr;
|
||||
pub mod sugg;
|
||||
pub mod sym;
|
||||
pub mod usage;
|
||||
pub use self::attrs::*;
|
||||
pub use self::diagnostics::*;
|
||||
|
@ -122,7 +124,7 @@ pub fn is_present_in_source<'a, T: LintContext<'a>>(cx: &T, span: Span) -> bool
|
|||
}
|
||||
|
||||
/// Checks if type is struct, enum or union type with the given def path.
|
||||
pub fn match_type(cx: &LateContext<'_, '_>, ty: Ty<'_>, path: &[Symbol]) -> bool {
|
||||
pub fn match_type(cx: &LateContext<'_, '_>, ty: Ty<'_>, path: &[&str]) -> bool {
|
||||
match ty.sty {
|
||||
ty::Adt(adt, _) => match_def_path(cx, adt.did, path),
|
||||
_ => false,
|
||||
|
@ -130,7 +132,7 @@ pub fn match_type(cx: &LateContext<'_, '_>, ty: Ty<'_>, path: &[Symbol]) -> bool
|
|||
}
|
||||
|
||||
/// Checks if the method call given in `expr` belongs to the given trait.
|
||||
pub fn match_trait_method(cx: &LateContext<'_, '_>, expr: &Expr, path: &[Symbol]) -> bool {
|
||||
pub fn match_trait_method(cx: &LateContext<'_, '_>, expr: &Expr, path: &[&str]) -> bool {
|
||||
let def_id = cx.tables.type_dependent_def_id(expr.hir_id).unwrap();
|
||||
let trt_id = cx.tcx.trait_of_item(def_id);
|
||||
if let Some(trt_id) = trt_id {
|
||||
|
@ -174,14 +176,14 @@ pub fn single_segment_path(path: &QPath) -> Option<&PathSegment> {
|
|||
/// ```rust,ignore
|
||||
/// match_qpath(path, &["std", "rt", "begin_unwind"])
|
||||
/// ```
|
||||
pub fn match_qpath(path: &QPath, segments: &[Symbol]) -> bool {
|
||||
pub fn match_qpath(path: &QPath, segments: &[&str]) -> bool {
|
||||
match *path {
|
||||
QPath::Resolved(_, ref path) => match_path(path, segments),
|
||||
QPath::TypeRelative(ref ty, ref segment) => match ty.node {
|
||||
TyKind::Path(ref inner_path) => {
|
||||
!segments.is_empty()
|
||||
&& match_qpath(inner_path, &segments[..(segments.len() - 1)])
|
||||
&& segment.ident.name == segments[segments.len() - 1]
|
||||
&& segment.ident.name.as_str() == segments[segments.len() - 1]
|
||||
},
|
||||
_ => false,
|
||||
},
|
||||
|
@ -196,7 +198,7 @@ pub fn match_qpath(path: &QPath, segments: &[Symbol]) -> bool {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// if match_path(&trait_ref.path, &*paths::HASH) {
|
||||
/// if match_path(&trait_ref.path, &paths::HASH) {
|
||||
/// // This is the `std::hash::Hash` trait.
|
||||
/// }
|
||||
///
|
||||
|
@ -204,12 +206,12 @@ pub fn match_qpath(path: &QPath, segments: &[Symbol]) -> bool {
|
|||
/// // This is a `rustc::lint::Lint`.
|
||||
/// }
|
||||
/// ```
|
||||
pub fn match_path(path: &Path, segments: &[Symbol]) -> bool {
|
||||
pub fn match_path(path: &Path, segments: &[&str]) -> bool {
|
||||
path.segments
|
||||
.iter()
|
||||
.rev()
|
||||
.zip(segments.iter().rev())
|
||||
.all(|(a, b)| a.ident.name == *b)
|
||||
.all(|(a, b)| a.ident.name.as_str() == *b)
|
||||
}
|
||||
|
||||
/// Matches a `Path` against a slice of segment string literals, e.g.
|
||||
|
@ -218,18 +220,18 @@ pub fn match_path(path: &Path, segments: &[Symbol]) -> bool {
|
|||
/// ```rust,ignore
|
||||
/// match_qpath(path, &["std", "rt", "begin_unwind"])
|
||||
/// ```
|
||||
pub fn match_path_ast(path: &ast::Path, segments: &[Symbol]) -> bool {
|
||||
pub fn match_path_ast(path: &ast::Path, segments: &[&str]) -> bool {
|
||||
path.segments
|
||||
.iter()
|
||||
.rev()
|
||||
.zip(segments.iter().rev())
|
||||
.all(|(a, b)| a.ident.name == *b)
|
||||
.all(|(a, b)| a.ident.name.as_str() == *b)
|
||||
}
|
||||
|
||||
/// Gets the definition associated to a path.
|
||||
pub fn path_to_res(cx: &LateContext<'_, '_>, path: &[Symbol]) -> Option<(def::Res)> {
|
||||
pub fn path_to_res(cx: &LateContext<'_, '_>, path: &[&str]) -> Option<(def::Res)> {
|
||||
let crates = cx.tcx.crates();
|
||||
let krate = crates.iter().find(|&&krate| cx.tcx.crate_name(krate) == path[0]);
|
||||
let krate = crates.iter().find(|&&krate| cx.tcx.crate_name(krate).as_str() == path[0]);
|
||||
if let Some(krate) = krate {
|
||||
let krate = DefId {
|
||||
krate: *krate,
|
||||
|
@ -245,7 +247,7 @@ pub fn path_to_res(cx: &LateContext<'_, '_>, path: &[Symbol]) -> Option<(def::Re
|
|||
};
|
||||
|
||||
for item in mem::replace(&mut items, Lrc::new(vec![])).iter() {
|
||||
if item.ident.name == *segment {
|
||||
if item.ident.name.as_str() == *segment {
|
||||
if path_it.peek().is_none() {
|
||||
return Some(item.res);
|
||||
}
|
||||
|
@ -261,7 +263,7 @@ pub fn path_to_res(cx: &LateContext<'_, '_>, path: &[Symbol]) -> Option<(def::Re
|
|||
}
|
||||
|
||||
/// Convenience function to get the `DefId` of a trait by path.
|
||||
pub fn get_trait_def_id(cx: &LateContext<'_, '_>, path: &[Symbol]) -> Option<DefId> {
|
||||
pub fn get_trait_def_id(cx: &LateContext<'_, '_>, path: &[&str]) -> Option<DefId> {
|
||||
let res = match path_to_res(cx, path) {
|
||||
Some(res) => res,
|
||||
None => return None,
|
||||
|
@ -364,13 +366,13 @@ pub fn method_calls<'a>(expr: &'a Expr, max_depth: usize) -> (Vec<Symbol>, Vec<&
|
|||
/// `matched_method_chain(expr, &["bar", "baz"])` will return a `Vec`
|
||||
/// containing the `Expr`s for
|
||||
/// `.bar()` and `.baz()`
|
||||
pub fn method_chain_args<'a>(expr: &'a Expr, methods: &[Symbol]) -> Option<Vec<&'a [Expr]>> {
|
||||
pub fn method_chain_args<'a>(expr: &'a Expr, methods: &[&str]) -> Option<Vec<&'a [Expr]>> {
|
||||
let mut current = expr;
|
||||
let mut matched = Vec::with_capacity(methods.len());
|
||||
for method_name in methods.iter().rev() {
|
||||
// method chains are stored last -> first
|
||||
if let ExprKind::MethodCall(ref path, _, ref args) = current.node {
|
||||
if path.ident.name == *method_name {
|
||||
if path.ident.name.as_str() == *method_name {
|
||||
if args.iter().any(|e| in_macro_or_desugar(e.span)) {
|
||||
return None;
|
||||
}
|
||||
|
@ -684,7 +686,7 @@ pub fn is_adjusted(cx: &LateContext<'_, '_>, e: &Expr) -> bool {
|
|||
/// Returns the pre-expansion span if is this comes from an expansion of the
|
||||
/// macro `name`.
|
||||
/// See also `is_direct_expn_of`.
|
||||
pub fn is_expn_of(mut span: Span, name: Symbol) -> Option<Span> {
|
||||
pub fn is_expn_of(mut span: Span, name: &str) -> Option<Span> {
|
||||
loop {
|
||||
let span_name_span = span
|
||||
.ctxt()
|
||||
|
@ -693,7 +695,7 @@ pub fn is_expn_of(mut span: Span, name: Symbol) -> Option<Span> {
|
|||
.map(|ei| (ei.format.name(), ei.call_site));
|
||||
|
||||
match span_name_span {
|
||||
Some((mac_name, new_span)) if mac_name == name => return Some(new_span),
|
||||
Some((mac_name, new_span)) if mac_name.as_str() == name => return Some(new_span),
|
||||
None => return None,
|
||||
Some((_, new_span)) => span = new_span,
|
||||
}
|
||||
|
@ -709,7 +711,7 @@ pub fn is_expn_of(mut span: Span, name: Symbol) -> Option<Span> {
|
|||
/// `42` is considered expanded from `foo!` and `bar!` by `is_expn_of` but only
|
||||
/// `bar!` by
|
||||
/// `is_direct_expn_of`.
|
||||
pub fn is_direct_expn_of(span: Span, name: Symbol) -> Option<Span> {
|
||||
pub fn is_direct_expn_of(span: Span, name: &str) -> Option<Span> {
|
||||
let span_name_span = span
|
||||
.ctxt()
|
||||
.outer()
|
||||
|
@ -717,7 +719,7 @@ pub fn is_direct_expn_of(span: Span, name: Symbol) -> Option<Span> {
|
|||
.map(|ei| (ei.format.name(), ei.call_site));
|
||||
|
||||
match span_name_span {
|
||||
Some((mac_name, new_span)) if mac_name == name => Some(new_span),
|
||||
Some((mac_name, new_span)) if mac_name.as_str() == name => Some(new_span),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -810,7 +812,7 @@ pub fn is_refutable(cx: &LateContext<'_, '_>, pat: &Pat) -> bool {
|
|||
/// Checks for the `#[automatically_derived]` attribute all `#[derive]`d
|
||||
/// implementations have.
|
||||
pub fn is_automatically_derived(attrs: &[ast::Attribute]) -> bool {
|
||||
attr::contains_name(attrs, *sym::automatically_derived)
|
||||
attr::contains_name(attrs, sym!(automatically_derived))
|
||||
}
|
||||
|
||||
/// Remove blocks around an expression.
|
||||
|
@ -996,24 +998,24 @@ pub fn any_parent_is_automatically_derived(tcx: TyCtxt<'_, '_, '_>, node: HirId)
|
|||
}
|
||||
|
||||
/// Returns true if ty has `iter` or `iter_mut` methods
|
||||
pub fn has_iter_method(cx: &LateContext<'_, '_>, probably_ref_ty: Ty<'_>) -> Option<Symbol> {
|
||||
pub fn has_iter_method(cx: &LateContext<'_, '_>, probably_ref_ty: Ty<'_>) -> Option<&'static str> {
|
||||
// FIXME: instead of this hard-coded list, we should check if `<adt>::iter`
|
||||
// exists and has the desired signature. Unfortunately FnCtxt is not exported
|
||||
// so we can't use its `lookup_method` method.
|
||||
let into_iter_collections: [&[Symbol]; 13] = [
|
||||
&*paths::VEC,
|
||||
&*paths::OPTION,
|
||||
&*paths::RESULT,
|
||||
&*paths::BTREESET,
|
||||
&*paths::BTREEMAP,
|
||||
&*paths::VEC_DEQUE,
|
||||
&*paths::LINKED_LIST,
|
||||
&*paths::BINARY_HEAP,
|
||||
&*paths::HASHSET,
|
||||
&*paths::HASHMAP,
|
||||
&*paths::PATH_BUF,
|
||||
&*paths::PATH,
|
||||
&*paths::RECEIVER,
|
||||
let into_iter_collections: [&[&str]; 13] = [
|
||||
&paths::VEC,
|
||||
&paths::OPTION,
|
||||
&paths::RESULT,
|
||||
&paths::BTREESET,
|
||||
&paths::BTREEMAP,
|
||||
&paths::VEC_DEQUE,
|
||||
&paths::LINKED_LIST,
|
||||
&paths::BINARY_HEAP,
|
||||
&paths::HASHSET,
|
||||
&paths::HASHMAP,
|
||||
&paths::PATH_BUF,
|
||||
&paths::PATH,
|
||||
&paths::RECEIVER,
|
||||
];
|
||||
|
||||
let ty_to_check = match probably_ref_ty.sty {
|
||||
|
@ -1022,8 +1024,8 @@ pub fn has_iter_method(cx: &LateContext<'_, '_>, probably_ref_ty: Ty<'_>) -> Opt
|
|||
};
|
||||
|
||||
let def_id = match ty_to_check.sty {
|
||||
ty::Array(..) => return Some(*sym::array),
|
||||
ty::Slice(..) => return Some(*sym::slice),
|
||||
ty::Array(..) => return Some("array"),
|
||||
ty::Slice(..) => return Some("slice"),
|
||||
ty::Adt(adt, _) => adt.did,
|
||||
_ => return None,
|
||||
};
|
||||
|
@ -1117,9 +1119,6 @@ mod test {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn match_def_path<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, did: DefId, syms: &[Symbol]) -> bool {
|
||||
// HACK: fix upstream `match_def_path` to take symbols
|
||||
let syms: Vec<_> = syms.iter().map(|sym| sym.as_str()).collect();
|
||||
let syms: Vec<_> = syms.iter().map(|sym| &**sym).collect();
|
||||
pub fn match_def_path<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, did: DefId, syms: &[&str]) -> bool {
|
||||
cx.match_def_path(did, &syms)
|
||||
}
|
||||
|
|
|
@ -1,123 +1,115 @@
|
|||
//! This module contains paths to types and functions Clippy needs to know
|
||||
//! about.
|
||||
|
||||
#![allow(default_hash_types)] // we just look at symbol names, which is good enough everywhere else
|
||||
|
||||
use super::sym::{self, *};
|
||||
use lazy_static::lazy_static;
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref ANY_TRAIT: [Symbol; 3] = [*std, *any, *Any];
|
||||
pub static ref ARC: [Symbol; 3] = [*alloc, *sync, *Arc];
|
||||
pub static ref ASMUT_TRAIT: [Symbol; 3] = [*core, *convert, *sym::AsMut];
|
||||
pub static ref ASREF_TRAIT: [Symbol; 3] = [*core, *convert, *sym::AsRef];
|
||||
pub static ref BEGIN_PANIC: [Symbol; 3] = [*std, *panicking, *begin_panic];
|
||||
pub static ref BEGIN_PANIC_FMT: [Symbol; 3] = [*std, *panicking, *begin_panic_fmt];
|
||||
pub static ref BINARY_HEAP: [Symbol; 4] = [*alloc, *collections, *binary_heap, *BinaryHeap];
|
||||
pub static ref BORROW_TRAIT: [Symbol; 3] = [*core, *borrow, *Borrow];
|
||||
pub static ref BTREEMAP: [Symbol; 5] = [*alloc, *collections, *btree, *map, *BTreeMap];
|
||||
pub static ref BTREEMAP_ENTRY: [Symbol; 5] = [*alloc, *collections, *btree, *map, *Entry];
|
||||
pub static ref BTREESET: [Symbol; 5] = [*alloc, *collections, *btree, *set, *BTreeSet];
|
||||
pub static ref CLONE_TRAIT: [Symbol; 3] = [*core, *clone, *sym::Clone];
|
||||
pub static ref CLONE_TRAIT_METHOD: [Symbol; 4] = [*core, *clone, *sym::Clone, *clone];
|
||||
pub static ref CMP_MAX: [Symbol; 3] = [*core, *cmp, *max];
|
||||
pub static ref CMP_MIN: [Symbol; 3] = [*core, *cmp, *min];
|
||||
pub static ref COW: [Symbol; 3] = [*alloc, *borrow, *Cow];
|
||||
pub static ref CSTRING_NEW: [Symbol; 5] = [*std, *ffi, *c_str, *CString, *new];
|
||||
pub static ref DEFAULT_TRAIT: [Symbol; 3] = [*core, *default, *sym::Default];
|
||||
pub static ref DEFAULT_TRAIT_METHOD: [Symbol; 4] = [*core, *default, *sym::Default, *default];
|
||||
pub static ref DEREF_TRAIT_METHOD: [Symbol; 5] = [*core, *ops, *deref, *Deref, *deref];
|
||||
pub static ref DISPLAY_FMT_METHOD: [Symbol; 4] = [*core, *fmt, *Display, *fmt];
|
||||
pub static ref DOUBLE_ENDED_ITERATOR: [Symbol; 4] = [*core, *iter, *traits, *sym::DoubleEndedIterator];
|
||||
pub static ref DROP: [Symbol; 3] = [*core, *mem, *drop];
|
||||
pub static ref DROP_TRAIT: [Symbol; 4] = [*core, *ops, *drop, *sym::Drop];
|
||||
pub static ref DURATION: [Symbol; 3] = [*core, *time, *Duration];
|
||||
pub static ref EARLY_CONTEXT: [Symbol; 4] = [*rustc, *lint, *context, *EarlyContext];
|
||||
pub static ref FMT_ARGUMENTS_NEWV1: [Symbol; 4] = [*core, *fmt, *Arguments, *new_v1];
|
||||
pub static ref FMT_ARGUMENTS_NEWV1FORMATTED: [Symbol; 4] = [*core, *fmt, *Arguments, *new_v1_formatted];
|
||||
pub static ref FROM_FROM: [Symbol; 4] = [*core, *convert, *sym::From, *from];
|
||||
pub static ref FROM_TRAIT: [Symbol; 3] = [*core, *convert, *sym::From];
|
||||
pub static ref HASH: [Symbol; 2] = [*hash, *Hash];
|
||||
pub static ref HASHMAP: [Symbol; 5] = [*std, *collections, *hash, *map, *HashMap];
|
||||
pub static ref HASHMAP_ENTRY: [Symbol; 5] = [*std, *collections, *hash, *map, *Entry];
|
||||
pub static ref HASHSET: [Symbol; 5] = [*std, *collections, *hash, *set, *HashSet];
|
||||
pub static ref INDEX: [Symbol; 3] = [*core, *ops, *Index];
|
||||
pub static ref INDEX_MUT: [Symbol; 3] = [*core, *ops, *IndexMut];
|
||||
pub static ref INIT: [Symbol; 4] = [*core, *intrinsics, *empty_symbol, *init];
|
||||
pub static ref INTO: [Symbol; 3] = [*core, *convert, *sym::Into];
|
||||
pub static ref INTO_ITERATOR: [Symbol; 5] = [*core, *iter, *traits, *collect, *sym::IntoIterator];
|
||||
pub static ref IO_READ: [Symbol; 3] = [*std, *io, *Read];
|
||||
pub static ref IO_WRITE: [Symbol; 3] = [*std, *io, *Write];
|
||||
pub static ref ITERATOR: [Symbol; 5] = [*core, *iter, *traits, *iterator, *sym::Iterator];
|
||||
pub static ref LATE_CONTEXT: [Symbol; 4] = [*rustc, *lint, *context, *LateContext];
|
||||
pub static ref LINKED_LIST: [Symbol; 4] = [*alloc, *collections, *linked_list, *LinkedList];
|
||||
pub static ref LINT: [Symbol; 3] = [*rustc, *lint, *Lint];
|
||||
pub static ref LINT_PASS: [Symbol; 3] = [*rustc, *lint, *LintPass];
|
||||
pub static ref MEM_DISCRIMINANT: [Symbol; 3] = [*core, *mem, *discriminant];
|
||||
pub static ref MEM_FORGET: [Symbol; 3] = [*core, *mem, *forget];
|
||||
pub static ref MEM_REPLACE: [Symbol; 3] = [*core, *mem, *replace];
|
||||
pub static ref MEM_UNINIT: [Symbol; 3] = [*core, *mem, *uninitialized];
|
||||
pub static ref MEM_ZEROED: [Symbol; 3] = [*core, *mem, *zeroed];
|
||||
pub static ref MUTEX: [Symbol; 4] = [*std, *sync, *mutex, *Mutex];
|
||||
pub static ref OPEN_OPTIONS: [Symbol; 3] = [*std, *fs, *OpenOptions];
|
||||
pub static ref OPS_MODULE: [Symbol; 2] = [*core, *ops];
|
||||
pub static ref OPTION: [Symbol; 3] = [*core, *option, *sym::Option];
|
||||
pub static ref OPTION_NONE: [Symbol; 4] = [*core, *option, *sym::Option, *sym::None];
|
||||
pub static ref OPTION_SOME: [Symbol; 4] = [*core, *option, *sym::Option, *sym::Some];
|
||||
pub static ref ORD: [Symbol; 3] = [*core, *cmp, *sym::Ord];
|
||||
pub static ref OS_STRING: [Symbol; 4] = [*std, *ffi, *os_str, *OsString];
|
||||
pub static ref OS_STR_TO_OS_STRING: [Symbol; 5] = [*std, *ffi, *os_str, *OsStr, *to_os_string];
|
||||
pub static ref PARTIAL_ORD: [Symbol; 3] = [*core, *cmp, *sym::PartialOrd];
|
||||
pub static ref PATH: [Symbol; 3] = [*std, *path, *Path];
|
||||
pub static ref PATH_BUF: [Symbol; 3] = [*std, *path, *PathBuf];
|
||||
pub static ref PATH_TO_PATH_BUF: [Symbol; 4] = [*std, *path, *Path, *to_path_buf];
|
||||
pub static ref PTR_NULL: [Symbol; 2] = [*ptr, *null];
|
||||
pub static ref PTR_NULL_MUT: [Symbol; 2] = [*ptr, *null_mut];
|
||||
pub static ref RANGE: [Symbol; 3] = [*core, *ops, *Range];
|
||||
pub static ref RANGE_ARGUMENT_TRAIT: [Symbol; 3] = [*core, *ops, *RangeBounds];
|
||||
pub static ref RANGE_FROM: [Symbol; 3] = [*core, *ops, *RangeFrom];
|
||||
pub static ref RANGE_FROM_STD: [Symbol; 3] = [*std, *ops, *RangeFrom];
|
||||
pub static ref RANGE_FULL: [Symbol; 3] = [*core, *ops, *RangeFull];
|
||||
pub static ref RANGE_FULL_STD: [Symbol; 3] = [*std, *ops, *RangeFull];
|
||||
pub static ref RANGE_INCLUSIVE_NEW: [Symbol; 4] = [*core, *ops, *RangeInclusive, *new];
|
||||
pub static ref RANGE_INCLUSIVE_STD_NEW: [Symbol; 4] = [*std, *ops, *RangeInclusive, *new];
|
||||
pub static ref RANGE_STD: [Symbol; 3] = [*std, *ops, *Range];
|
||||
pub static ref RANGE_TO: [Symbol; 3] = [*core, *ops, *RangeTo];
|
||||
pub static ref RANGE_TO_INCLUSIVE: [Symbol; 3] = [*core, *ops, *RangeToInclusive];
|
||||
pub static ref RANGE_TO_INCLUSIVE_STD: [Symbol; 3] = [*std, *ops, *RangeToInclusive];
|
||||
pub static ref RANGE_TO_STD: [Symbol; 3] = [*std, *ops, *RangeTo];
|
||||
pub static ref RC: [Symbol; 3] = [*alloc, *rc, *Rc];
|
||||
pub static ref RECEIVER: [Symbol; 4] = [*std, *sync, *mpsc, *Receiver];
|
||||
pub static ref REGEX: [Symbol; 3] = [*regex, *re_unicode, *Regex];
|
||||
pub static ref REGEX_BUILDER_NEW: [Symbol; 5] = [*regex, *re_builder, *unicode, *RegexBuilder, *new];
|
||||
pub static ref REGEX_BYTES_BUILDER_NEW: [Symbol; 5] = [*regex, *re_builder, *bytes, *RegexBuilder, *new];
|
||||
pub static ref REGEX_BYTES_NEW: [Symbol; 4] = [*regex, *re_bytes, *Regex, *new];
|
||||
pub static ref REGEX_BYTES_SET_NEW: [Symbol; 5] = [*regex, *re_set, *bytes, *RegexSet, *new];
|
||||
pub static ref REGEX_NEW: [Symbol; 4] = [*regex, *re_unicode, *Regex, *new];
|
||||
pub static ref REGEX_SET_NEW: [Symbol; 5] = [*regex, *re_set, *unicode, *RegexSet, *new];
|
||||
pub static ref REPEAT: [Symbol; 3] = [*core, *iter, *repeat];
|
||||
pub static ref RESULT: [Symbol; 3] = [*core, *result, *sym::Result];
|
||||
pub static ref RESULT_ERR: [Symbol; 4] = [*core, *result, *sym::Result, *sym::Err];
|
||||
pub static ref RESULT_OK: [Symbol; 4] = [*core, *result, *sym::Result, *sym::Ok];
|
||||
pub static ref SERDE_DE_VISITOR: [Symbol; 3] = [*serde, *de, *Visitor];
|
||||
pub static ref SLICE_INTO_VEC: [Symbol; 4] = [*alloc, *slice, *impl_slice_t, *into_vec];
|
||||
pub static ref SLICE_ITER: [Symbol; 3] = [*core, *slice, *Iter];
|
||||
pub static ref STD_MEM_TRANSMUTE: [Symbol; 3] = [*std, *mem, *transmute];
|
||||
pub static ref STD_PTR_NULL: [Symbol; 3] = [*std, *ptr, *null];
|
||||
pub static ref STDERR: [Symbol; 4] = [*std, *io, *stdio, *stderr];
|
||||
pub static ref STDOUT: [Symbol; 4] = [*std, *io, *stdio, *stdout];
|
||||
pub static ref STRING: [Symbol; 3] = [*alloc, *string, *sym::String];
|
||||
pub static ref TO_OWNED: [Symbol; 3] = [*alloc, *borrow, *sym::ToOwned];
|
||||
pub static ref TO_OWNED_METHOD: [Symbol; 4] = [*alloc, *borrow, *sym::ToOwned, *to_owned];
|
||||
pub static ref TO_STRING: [Symbol; 3] = [*alloc, *string, *sym::ToString];
|
||||
pub static ref TO_STRING_METHOD: [Symbol; 4] = [*alloc, *string, *sym::ToString, *to_string];
|
||||
pub static ref TRANSMUTE: [Symbol; 4] = [*core, *intrinsics, *empty_symbol, *transmute];
|
||||
pub static ref TRY_INTO_RESULT: [Symbol; 4] = [*std, *ops, *Try, *into_result];
|
||||
pub static ref UNINIT: [Symbol; 4] = [*core, *intrinsics, *empty_symbol, *uninit];
|
||||
pub static ref VEC: [Symbol; 3] = [*alloc, *vec, *sym::Vec];
|
||||
pub static ref VEC_DEQUE: [Symbol; 4] = [*alloc, *collections, *vec_deque, *VecDeque];
|
||||
pub static ref VEC_FROM_ELEM: [Symbol; 3] = [*alloc, *vec, *from_elem];
|
||||
pub static ref WEAK_ARC: [Symbol; 3] = [*alloc, *sync, *Weak];
|
||||
pub static ref WEAK_RC: [Symbol; 3] = [*alloc, *rc, *Weak];
|
||||
}
|
||||
pub const ANY_TRAIT: [&str; 3] = ["std", "any", "Any"];
|
||||
pub const ARC: [&str; 3] = ["alloc", "sync", "Arc"];
|
||||
pub const ASMUT_TRAIT: [&str; 3] = ["core", "convert", "AsMut"];
|
||||
pub const ASREF_TRAIT: [&str; 3] = ["core", "convert", "AsRef"];
|
||||
pub const BEGIN_PANIC: [&str; 3] = ["std", "panicking", "begin_panic"];
|
||||
pub const BEGIN_PANIC_FMT: [&str; 3] = ["std", "panicking", "begin_panic_fmt"];
|
||||
pub const BINARY_HEAP: [&str; 4] = ["alloc", "collections", "binary_heap", "BinaryHeap"];
|
||||
pub const BORROW_TRAIT: [&str; 3] = ["core", "borrow", "Borrow"];
|
||||
pub const BTREEMAP: [&str; 5] = ["alloc", "collections", "btree", "map", "BTreeMap"];
|
||||
pub const BTREEMAP_ENTRY: [&str; 5] = ["alloc", "collections", "btree", "map", "Entry"];
|
||||
pub const BTREESET: [&str; 5] = ["alloc", "collections", "btree", "set", "BTreeSet"];
|
||||
pub const CLONE_TRAIT: [&str; 3] = ["core", "clone", "Clone"];
|
||||
pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"];
|
||||
pub const CMP_MAX: [&str; 3] = ["core", "cmp", "max"];
|
||||
pub const CMP_MIN: [&str; 3] = ["core", "cmp", "min"];
|
||||
pub const COW: [&str; 3] = ["alloc", "borrow", "Cow"];
|
||||
pub const CSTRING_NEW: [&str; 5] = ["std", "ffi", "c_str", "CString", "new"];
|
||||
pub const DEFAULT_TRAIT: [&str; 3] = ["core", "default", "Default"];
|
||||
pub const DEFAULT_TRAIT_METHOD: [&str; 4] = ["core", "default", "Default", "default"];
|
||||
pub const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref", "deref"];
|
||||
pub const DISPLAY_FMT_METHOD: [&str; 4] = ["core", "fmt", "Display", "fmt"];
|
||||
pub const DOUBLE_ENDED_ITERATOR: [&str; 4] = ["core", "iter", "traits", "DoubleEndedIterator"];
|
||||
pub const DROP: [&str; 3] = ["core", "mem", "drop"];
|
||||
pub const DROP_TRAIT: [&str; 4] = ["core", "ops", "drop", "Drop"];
|
||||
pub const DURATION: [&str; 3] = ["core", "time", "Duration"];
|
||||
pub const EARLY_CONTEXT: [&str; 4] = ["rustc", "lint", "context", "EarlyContext"];
|
||||
pub const FMT_ARGUMENTS_NEWV1: [&str; 4] = ["core", "fmt", "Arguments", "new_v1"];
|
||||
pub const FMT_ARGUMENTS_NEWV1FORMATTED: [&str; 4] = ["core", "fmt", "Arguments", "new_v1_formatted"];
|
||||
pub const FROM_FROM: [&str; 4] = ["core", "convert", "From", "from"];
|
||||
pub const FROM_TRAIT: [&str; 3] = ["core", "convert", "From"];
|
||||
pub const HASH: [&str; 2] = ["hash", "Hash"];
|
||||
pub const HASHMAP: [&str; 5] = ["std", "collections", "hash", "map", "HashMap"];
|
||||
pub const HASHMAP_ENTRY: [&str; 5] = ["std", "collections", "hash", "map", "Entry"];
|
||||
pub const HASHSET: [&str; 5] = ["std", "collections", "hash", "set", "HashSet"];
|
||||
pub const INDEX: [&str; 3] = ["core", "ops", "Index"];
|
||||
pub const INDEX_MUT: [&str; 3] = ["core", "ops", "IndexMut"];
|
||||
pub const INIT: [&str; 4] = ["core", "intrinsics", "", "init"];
|
||||
pub const INTO: [&str; 3] = ["core", "convert", "Into"];
|
||||
pub const INTO_ITERATOR: [&str; 5] = ["core", "iter", "traits", "collect", "IntoIterator"];
|
||||
pub const IO_READ: [&str; 3] = ["std", "io", "Read"];
|
||||
pub const IO_WRITE: [&str; 3] = ["std", "io", "Write"];
|
||||
pub const ITERATOR: [&str; 5] = ["core", "iter", "traits", "iterator", "Iterator"];
|
||||
pub const LATE_CONTEXT: [&str; 4] = ["rustc", "lint", "context", "LateContext"];
|
||||
pub const LINKED_LIST: [&str; 4] = ["alloc", "collections", "linked_list", "LinkedList"];
|
||||
pub const LINT: [&str; 3] = ["rustc", "lint", "Lint"];
|
||||
pub const LINT_PASS: [&str; 3] = ["rustc", "lint", "LintPass"];
|
||||
pub const MEM_DISCRIMINANT: [&str; 3] = ["core", "mem", "discriminant"];
|
||||
pub const MEM_FORGET: [&str; 3] = ["core", "mem", "forget"];
|
||||
pub const MEM_REPLACE: [&str; 3] = ["core", "mem", "replace"];
|
||||
pub const MEM_UNINIT: [&str; 3] = ["core", "mem", "uninitialized"];
|
||||
pub const MEM_ZEROED: [&str; 3] = ["core", "mem", "zeroed"];
|
||||
pub const MUTEX: [&str; 4] = ["std", "sync", "mutex", "Mutex"];
|
||||
pub const OPEN_OPTIONS: [&str; 3] = ["std", "fs", "OpenOptions"];
|
||||
pub const OPS_MODULE: [&str; 2] = ["core", "ops"];
|
||||
pub const OPTION: [&str; 3] = ["core", "option", "Option"];
|
||||
pub const OPTION_NONE: [&str; 4] = ["core", "option", "Option", "None"];
|
||||
pub const OPTION_SOME: [&str; 4] = ["core", "option", "Option", "Some"];
|
||||
pub const ORD: [&str; 3] = ["core", "cmp", "Ord"];
|
||||
pub const OS_STRING: [&str; 4] = ["std", "ffi", "os_str", "OsString"];
|
||||
pub const OS_STR_TO_OS_STRING: [&str; 5] = ["std", "ffi", "os_str", "OsStr", "to_os_string"];
|
||||
pub const PARTIAL_ORD: [&str; 3] = ["core", "cmp", "PartialOrd"];
|
||||
pub const PATH: [&str; 3] = ["std", "path", "Path"];
|
||||
pub const PATH_BUF: [&str; 3] = ["std", "path", "PathBuf"];
|
||||
pub const PATH_TO_PATH_BUF: [&str; 4] = ["std", "path", "Path", "to_path_buf"];
|
||||
pub const PTR_NULL: [&str; 2] = ["ptr", "null"];
|
||||
pub const PTR_NULL_MUT: [&str; 2] = ["ptr", "null_mut"];
|
||||
pub const RANGE: [&str; 3] = ["core", "ops", "Range"];
|
||||
pub const RANGE_ARGUMENT_TRAIT: [&str; 3] = ["core", "ops", "RangeBounds"];
|
||||
pub const RANGE_FROM: [&str; 3] = ["core", "ops", "RangeFrom"];
|
||||
pub const RANGE_FROM_STD: [&str; 3] = ["std", "ops", "RangeFrom"];
|
||||
pub const RANGE_FULL: [&str; 3] = ["core", "ops", "RangeFull"];
|
||||
pub const RANGE_FULL_STD: [&str; 3] = ["std", "ops", "RangeFull"];
|
||||
pub const RANGE_INCLUSIVE_NEW: [&str; 4] = ["core", "ops", "RangeInclusive", "new"];
|
||||
pub const RANGE_INCLUSIVE_STD_NEW: [&str; 4] = ["std", "ops", "RangeInclusive", "new"];
|
||||
pub const RANGE_STD: [&str; 3] = ["std", "ops", "Range"];
|
||||
pub const RANGE_TO: [&str; 3] = ["core", "ops", "RangeTo"];
|
||||
pub const RANGE_TO_INCLUSIVE: [&str; 3] = ["core", "ops", "RangeToInclusive"];
|
||||
pub const RANGE_TO_INCLUSIVE_STD: [&str; 3] = ["std", "ops", "RangeToInclusive"];
|
||||
pub const RANGE_TO_STD: [&str; 3] = ["std", "ops", "RangeTo"];
|
||||
pub const RC: [&str; 3] = ["alloc", "rc", "Rc"];
|
||||
pub const RECEIVER: [&str; 4] = ["std", "sync", "mpsc", "Receiver"];
|
||||
pub const REGEX: [&str; 3] = ["regex", "re_unicode", "Regex"];
|
||||
pub const REGEX_BUILDER_NEW: [&str; 5] = ["regex", "re_builder", "unicode", "RegexBuilder", "new"];
|
||||
pub const REGEX_BYTES_BUILDER_NEW: [&str; 5] = ["regex", "re_builder", "bytes", "RegexBuilder", "new"];
|
||||
pub const REGEX_BYTES_NEW: [&str; 4] = ["regex", "re_bytes", "Regex", "new"];
|
||||
pub const REGEX_BYTES_SET_NEW: [&str; 5] = ["regex", "re_set", "bytes", "RegexSet", "new"];
|
||||
pub const REGEX_NEW: [&str; 4] = ["regex", "re_unicode", "Regex", "new"];
|
||||
pub const REGEX_SET_NEW: [&str; 5] = ["regex", "re_set", "unicode", "RegexSet", "new"];
|
||||
pub const REPEAT: [&str; 3] = ["core", "iter", "repeat"];
|
||||
pub const RESULT: [&str; 3] = ["core", "result", "Result"];
|
||||
pub const RESULT_ERR: [&str; 4] = ["core", "result", "Result", "Err"];
|
||||
pub const RESULT_OK: [&str; 4] = ["core", "result", "Result", "Ok"];
|
||||
pub const SERDE_DE_VISITOR: [&str; 3] = ["serde", "de", "Visitor"];
|
||||
pub const SLICE_INTO_VEC: [&str; 4] = ["alloc", "slice", "<impl [T]>", "into_vec"];
|
||||
pub const SLICE_ITER: [&str; 3] = ["core", "slice", "Iter"];
|
||||
pub const STD_MEM_TRANSMUTE: [&str; 3] = ["std", "mem", "transmute"];
|
||||
pub const STD_PTR_NULL: [&str; 3] = ["std", "ptr", "null"];
|
||||
pub const STDERR: [&str; 4] = ["std", "io", "stdio", "stderr"];
|
||||
pub const STDOUT: [&str; 4] = ["std", "io", "stdio", "stdout"];
|
||||
pub const STRING: [&str; 3] = ["alloc", "string", "String"];
|
||||
pub const TO_OWNED: [&str; 3] = ["alloc", "borrow", "ToOwned"];
|
||||
pub const TO_OWNED_METHOD: [&str; 4] = ["alloc", "borrow", "ToOwned", "to_owned"];
|
||||
pub const TO_STRING: [&str; 3] = ["alloc", "string", "ToString"];
|
||||
pub const TO_STRING_METHOD: [&str; 4] = ["alloc", "string", "ToString", "to_string"];
|
||||
pub const TRANSMUTE: [&str; 4] = ["core", "intrinsics", "", "transmute"];
|
||||
pub const TRY_INTO_RESULT: [&str; 4] = ["std", "ops", "Try", "into_result"];
|
||||
pub const UNINIT: [&str; 4] = ["core", "intrinsics", "", "uninit"];
|
||||
pub const VEC: [&str; 3] = ["alloc", "vec", "Vec"];
|
||||
pub const VEC_DEQUE: [&str; 4] = ["alloc", "collections", "vec_deque", "VecDeque"];
|
||||
pub const VEC_FROM_ELEM: [&str; 3] = ["alloc", "vec", "from_elem"];
|
||||
pub const WEAK_ARC: [&str; 3] = ["alloc", "sync", "Weak"];
|
||||
pub const WEAK_RC: [&str; 3] = ["alloc", "rc", "Weak"];
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::utils::sym;
|
||||
use crate::utils::{get_pat_name, match_var, snippet};
|
||||
use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
|
||||
use rustc::hir::*;
|
||||
|
@ -6,13 +5,12 @@ use rustc::lint::LateContext;
|
|||
use std::borrow::Cow;
|
||||
use syntax::ast::Name;
|
||||
use syntax::source_map::Span;
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
pub fn get_spans(
|
||||
cx: &LateContext<'_, '_>,
|
||||
opt_body_id: Option<BodyId>,
|
||||
idx: usize,
|
||||
replacements: &[(Symbol, &'static str)],
|
||||
replacements: &[(&'static str, &'static str)],
|
||||
) -> Option<Vec<(Span, Cow<'static, str>)>> {
|
||||
if let Some(body) = opt_body_id.map(|id| cx.tcx.hir().body(id)) {
|
||||
get_binding_name(&body.arguments[idx]).map_or_else(
|
||||
|
@ -27,7 +25,7 @@ pub fn get_spans(
|
|||
fn extract_clone_suggestions<'a, 'tcx: 'a>(
|
||||
cx: &LateContext<'a, 'tcx>,
|
||||
name: Name,
|
||||
replace: &[(Symbol, &'static str)],
|
||||
replace: &[(&'static str, &'static str)],
|
||||
body: &'tcx Body,
|
||||
) -> Option<Vec<(Span, Cow<'static, str>)>> {
|
||||
let mut visitor = PtrCloneVisitor {
|
||||
|
@ -48,7 +46,7 @@ fn extract_clone_suggestions<'a, 'tcx: 'a>(
|
|||
struct PtrCloneVisitor<'a, 'tcx: 'a> {
|
||||
cx: &'a LateContext<'a, 'tcx>,
|
||||
name: Name,
|
||||
replace: &'a [(Symbol, &'static str)],
|
||||
replace: &'a [(&'static str, &'static str)],
|
||||
spans: Vec<(Span, Cow<'static, str>)>,
|
||||
abort: bool,
|
||||
}
|
||||
|
@ -60,12 +58,12 @@ impl<'a, 'tcx: 'a> Visitor<'tcx> for PtrCloneVisitor<'a, 'tcx> {
|
|||
}
|
||||
if let ExprKind::MethodCall(ref seg, _, ref args) = expr.node {
|
||||
if args.len() == 1 && match_var(&args[0], self.name) {
|
||||
if seg.ident.name == *sym::capacity {
|
||||
if seg.ident.name.as_str() == "capacity" {
|
||||
self.abort = true;
|
||||
return;
|
||||
}
|
||||
for &(fn_name, suffix) in self.replace {
|
||||
if seg.ident.name == fn_name {
|
||||
if seg.ident.name.as_str() == fn_name {
|
||||
self.spans
|
||||
.push((expr.span, snippet(self.cx, args[0].span, "_") + suffix));
|
||||
return;
|
||||
|
|
|
@ -1,393 +1,7 @@
|
|||
#![allow(default_hash_types, non_upper_case_globals)]
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
macro_rules! symbols_simple {
|
||||
($($ident:ident,)*) => {
|
||||
$(
|
||||
lazy_static! {
|
||||
pub(crate) static ref $ident: Symbol = Symbol::intern(stringify!($ident));
|
||||
}
|
||||
)*
|
||||
#[macro_export]
|
||||
macro_rules! sym {
|
||||
($tt:tt) => {
|
||||
syntax::symbol::Symbol::intern(stringify!($tt))
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! symbols_init {
|
||||
($($ident:ident: $expr:expr,)*) => {
|
||||
$(
|
||||
lazy_static! {
|
||||
pub(crate) static ref $ident: Symbol = Symbol::intern($expr);
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
// exists because concat_idents is flaky
|
||||
pub mod assign {
|
||||
pub(crate) use super::AddAssign as Add;
|
||||
pub(crate) use super::AndAssign as And;
|
||||
pub(crate) use super::BitAndAssign as BitAnd;
|
||||
pub(crate) use super::BitOrAssign as BitOr;
|
||||
pub(crate) use super::BitXorAssign as BitXor;
|
||||
pub(crate) use super::DivAssign as Div;
|
||||
pub(crate) use super::MulAssign as Mul;
|
||||
pub(crate) use super::OrAssign as Or;
|
||||
pub(crate) use super::RemAssign as Rem;
|
||||
pub(crate) use super::ShlAssign as Shl;
|
||||
pub(crate) use super::ShrAssign as Shr;
|
||||
pub(crate) use super::SubAssign as Sub;
|
||||
}
|
||||
|
||||
symbols_simple! {
|
||||
Option,
|
||||
rustc,
|
||||
AsMut,
|
||||
AsRef,
|
||||
Clone,
|
||||
Default,
|
||||
DoubleEndedIterator,
|
||||
Drop,
|
||||
From,
|
||||
Into,
|
||||
IntoIterator,
|
||||
Iterator,
|
||||
Ord,
|
||||
PartialOrd,
|
||||
Any,
|
||||
add,
|
||||
Add,
|
||||
AddAssign,
|
||||
AndAssign,
|
||||
OrAssign,
|
||||
all,
|
||||
alloc,
|
||||
always,
|
||||
any,
|
||||
Arc,
|
||||
Arguments,
|
||||
array,
|
||||
as_bytes,
|
||||
as_mut,
|
||||
as_ref,
|
||||
assert,
|
||||
as_str,
|
||||
automatically_derived,
|
||||
begin_panic,
|
||||
begin_panic_fmt,
|
||||
binary_heap,
|
||||
BinaryHeap,
|
||||
bitand,
|
||||
BitAndAssign,
|
||||
bitor,
|
||||
BitOrAssign,
|
||||
bitxor,
|
||||
BitXorAssign,
|
||||
bool,
|
||||
borrow,
|
||||
Borrow,
|
||||
borrow_mut,
|
||||
btree,
|
||||
BTreeMap,
|
||||
BTreeSet,
|
||||
by_ref,
|
||||
bytes,
|
||||
capacity,
|
||||
cfg,
|
||||
cfg_attr,
|
||||
chain,
|
||||
chars,
|
||||
clone,
|
||||
cloned,
|
||||
cmp,
|
||||
collect,
|
||||
collections,
|
||||
conf_file,
|
||||
contains,
|
||||
contains_key,
|
||||
context,
|
||||
convert,
|
||||
core,
|
||||
count,
|
||||
Cow,
|
||||
c_str,
|
||||
CString,
|
||||
cycle,
|
||||
dbg,
|
||||
de,
|
||||
debug_assert,
|
||||
default,
|
||||
deprecated,
|
||||
deref,
|
||||
Deref,
|
||||
deref_mut,
|
||||
discriminant,
|
||||
Display,
|
||||
div,
|
||||
Div,
|
||||
DivAssign,
|
||||
doc,
|
||||
drop,
|
||||
Duration,
|
||||
E,
|
||||
EarlyContext,
|
||||
end,
|
||||
ends_with,
|
||||
Entry,
|
||||
enumerate,
|
||||
eq,
|
||||
Err,
|
||||
extend,
|
||||
ffi,
|
||||
filter,
|
||||
filter_map,
|
||||
find,
|
||||
flat_map,
|
||||
fmt,
|
||||
fold,
|
||||
for_each,
|
||||
forget,
|
||||
format,
|
||||
FRAC_1_PI,
|
||||
FRAC_1_SQRT_2,
|
||||
FRAC_2_PI,
|
||||
FRAC_2_SQRT_PI,
|
||||
FRAC_PI_2,
|
||||
FRAC_PI_3,
|
||||
FRAC_PI_4,
|
||||
FRAC_PI_6,
|
||||
FRAC_PI_8,
|
||||
from,
|
||||
from_elem,
|
||||
from_iter,
|
||||
from_str,
|
||||
fs,
|
||||
fuse,
|
||||
hash,
|
||||
Hash,
|
||||
HashMap,
|
||||
HashSet,
|
||||
hidden,
|
||||
i128,
|
||||
i16,
|
||||
i32,
|
||||
i64,
|
||||
i8,
|
||||
Implied,
|
||||
index,
|
||||
Index,
|
||||
index_mut,
|
||||
IndexMut,
|
||||
init,
|
||||
inline,
|
||||
insert,
|
||||
inspect,
|
||||
into_iter,
|
||||
into_result,
|
||||
into_vec,
|
||||
intrinsics,
|
||||
io,
|
||||
is_empty,
|
||||
is_err,
|
||||
isize,
|
||||
is_none,
|
||||
is_ok,
|
||||
is_some,
|
||||
iter,
|
||||
Iter,
|
||||
iterator,
|
||||
iter_mut,
|
||||
last,
|
||||
LateContext,
|
||||
len,
|
||||
linked_list,
|
||||
LinkedList,
|
||||
lint,
|
||||
Lint,
|
||||
LintPass,
|
||||
LN_10,
|
||||
LN_2,
|
||||
LOG10_E,
|
||||
LOG2_E,
|
||||
macro_use,
|
||||
main,
|
||||
map,
|
||||
matches,
|
||||
match_indices,
|
||||
max,
|
||||
MAX,
|
||||
max_by,
|
||||
max_by_key,
|
||||
mem,
|
||||
min,
|
||||
MIN,
|
||||
min_by,
|
||||
min_by_key,
|
||||
mpsc,
|
||||
mul,
|
||||
Mul,
|
||||
MulAssign,
|
||||
mutex,
|
||||
Mutex,
|
||||
NAN,
|
||||
ne,
|
||||
neg,
|
||||
new,
|
||||
new_v1,
|
||||
new_v1_formatted,
|
||||
next,
|
||||
next_back,
|
||||
None,
|
||||
not,
|
||||
null,
|
||||
null_mut,
|
||||
offset,
|
||||
ok,
|
||||
Ok,
|
||||
ONCE_INIT,
|
||||
open,
|
||||
OpenOptions,
|
||||
ops,
|
||||
option,
|
||||
os_str,
|
||||
OsStr,
|
||||
OsString,
|
||||
panic,
|
||||
panicking,
|
||||
partition,
|
||||
path,
|
||||
Path,
|
||||
PathBuf,
|
||||
paths,
|
||||
peekable,
|
||||
PI,
|
||||
position,
|
||||
precision,
|
||||
print,
|
||||
println,
|
||||
proc_macro,
|
||||
proc_macro_attribute,
|
||||
proc_macro_derive,
|
||||
product,
|
||||
ptr,
|
||||
push,
|
||||
Range,
|
||||
RangeBounds,
|
||||
RangeFrom,
|
||||
RangeFull,
|
||||
RangeInclusive,
|
||||
RangeTo,
|
||||
RangeToInclusive,
|
||||
rc,
|
||||
Rc,
|
||||
Read,
|
||||
re_builder,
|
||||
re_bytes,
|
||||
Receiver,
|
||||
regex,
|
||||
Regex,
|
||||
RegexBuilder,
|
||||
RegexSet,
|
||||
rem,
|
||||
RemAssign,
|
||||
repeat,
|
||||
replace,
|
||||
re_set,
|
||||
resize,
|
||||
result,
|
||||
Result,
|
||||
re_unicode,
|
||||
rev,
|
||||
rfind,
|
||||
rmatches,
|
||||
rmatch_indices,
|
||||
rplit_terminator,
|
||||
rposition,
|
||||
rsplit,
|
||||
rsplitn,
|
||||
rsplit_terminator,
|
||||
rustfmt,
|
||||
rustfmt_skip,
|
||||
scan,
|
||||
serde,
|
||||
set,
|
||||
shl,
|
||||
ShlAssign,
|
||||
shr,
|
||||
ShrAssign,
|
||||
since,
|
||||
skip,
|
||||
skip_while,
|
||||
slice,
|
||||
Some,
|
||||
split,
|
||||
splitn,
|
||||
split_terminator,
|
||||
SQRT_2,
|
||||
start,
|
||||
starts_with,
|
||||
std,
|
||||
stderr,
|
||||
stdin,
|
||||
stdio,
|
||||
stdout,
|
||||
string,
|
||||
String,
|
||||
sub,
|
||||
Sub,
|
||||
SubAssign,
|
||||
sum,
|
||||
sync,
|
||||
take,
|
||||
take_while,
|
||||
test,
|
||||
time,
|
||||
to_os_string,
|
||||
to_owned,
|
||||
ToOwned,
|
||||
to_path_buf,
|
||||
to_string,
|
||||
ToString,
|
||||
traits,
|
||||
transmute,
|
||||
trim_end_matches,
|
||||
trim_start_matches,
|
||||
Try,
|
||||
u128,
|
||||
u16,
|
||||
u32,
|
||||
u64,
|
||||
u8,
|
||||
unicode,
|
||||
unimplemented,
|
||||
uninit,
|
||||
uninitialized,
|
||||
unreachable,
|
||||
unused_extern_crates,
|
||||
unused_imports,
|
||||
unwrap,
|
||||
unwrap_err,
|
||||
unzip,
|
||||
usize,
|
||||
utils,
|
||||
vec,
|
||||
Vec,
|
||||
vec_deque,
|
||||
VecDeque,
|
||||
Visitor,
|
||||
Weak,
|
||||
width,
|
||||
with_capacity,
|
||||
wrapping_offset,
|
||||
write,
|
||||
Write,
|
||||
write_fmt,
|
||||
writeln,
|
||||
zeroed,
|
||||
zip,
|
||||
}
|
||||
|
||||
symbols_init! {
|
||||
impl_slice_t: "<impl [T]>",
|
||||
empty_symbol: "",
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use crate::utils::{snippet_with_applicability, span_lint, span_lint_and_sugg, sym};
|
||||
use crate::utils::{snippet_with_applicability, span_lint, span_lint_and_sugg};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_errors::Applicability;
|
||||
use std::borrow::Cow;
|
||||
use syntax::ast::*;
|
||||
use syntax::parse::{parser, token};
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax::tokenstream::{TokenStream, TokenTree};
|
||||
use syntax_pos::symbol::Symbol;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** This lint warns when you use `println!("")` to
|
||||
|
@ -182,7 +182,7 @@ declare_lint_pass!(Write => [
|
|||
|
||||
impl EarlyLintPass for Write {
|
||||
fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &Mac) {
|
||||
if mac.node.path == *sym::println {
|
||||
if mac.node.path == sym!(println) {
|
||||
span_lint(cx, PRINT_STDOUT, mac.span, "use of `println!`");
|
||||
if let Some(fmtstr) = check_tts(cx, &mac.node.tts, false).0 {
|
||||
if fmtstr == "" {
|
||||
|
@ -197,7 +197,7 @@ impl EarlyLintPass for Write {
|
|||
);
|
||||
}
|
||||
}
|
||||
} else if mac.node.path == *sym::print {
|
||||
} else if mac.node.path == sym!(print) {
|
||||
span_lint(cx, PRINT_STDOUT, mac.span, "use of `print!`");
|
||||
if let (Some(fmtstr), _, is_raw) = check_tts(cx, &mac.node.tts, false) {
|
||||
if check_newlines(&fmtstr, is_raw) {
|
||||
|
@ -210,7 +210,7 @@ impl EarlyLintPass for Write {
|
|||
);
|
||||
}
|
||||
}
|
||||
} else if mac.node.path == *sym::write {
|
||||
} else if mac.node.path == sym!(write) {
|
||||
if let (Some(fmtstr), _, is_raw) = check_tts(cx, &mac.node.tts, true) {
|
||||
if check_newlines(&fmtstr, is_raw) {
|
||||
span_lint(
|
||||
|
@ -222,7 +222,7 @@ impl EarlyLintPass for Write {
|
|||
);
|
||||
}
|
||||
}
|
||||
} else if mac.node.path == *sym::writeln {
|
||||
} else if mac.node.path == sym!(writeln) {
|
||||
let check_tts = check_tts(cx, &mac.node.tts, true);
|
||||
if let Some(fmtstr) = check_tts.0 {
|
||||
if fmtstr == "" {
|
||||
|
@ -365,8 +365,6 @@ fn check_tts<'a>(cx: &EarlyContext<'a>, tts: &TokenStream, is_write: bool) -> (O
|
|||
match arg.position {
|
||||
ArgumentImplicitlyIs(_) | ArgumentIs(_) => {},
|
||||
ArgumentNamed(name) => {
|
||||
// FIXME: remove this interning if possible
|
||||
// https://github.com/rust-lang/rust/issues/60795
|
||||
if *p == Symbol::intern(name) {
|
||||
seen = true;
|
||||
all_simple &= arg.format == SIMPLE;
|
||||
|
|
Loading…
Reference in a new issue