Prevent symbocalypse

This commit is contained in:
Oliver Scherer 2019-05-17 23:53:54 +02:00
parent 11194e3d05
commit f7f85a0dca
78 changed files with 686 additions and 1160 deletions

View file

@ -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]);

View file

@ -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);

View file

@ -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 {

View file

@ -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;

View file

@ -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, &[]))
}

View file

@ -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]

View file

@ -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);
}
}

View file

@ -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,

View file

@ -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,

View file

@ -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(..) => {

View file

@ -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;
}

View file

@ -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(&current_spans);
doc.push_str(&current);
}
} else if attr.check_name(*sym::doc) {
} else if attr.check_name(sym!(doc)) {
// ignore mix of sugared and non-sugared doc
return;
}

View file

@ -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,

View file

@ -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 {

View file

@ -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) {

View file

@ -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 = &params[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, &params[0]);
if SpanlessEq::new(self.cx).eq_expr(self.key, &params[1]);
then {

View file

@ -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

View file

@ -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,

View file

@ -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;
}

View file

@ -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) {

View file

@ -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")
}
},

View file

@ -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]);

View file

@ -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;
}

View file

@ -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 {

View file

@ -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

View file

@ -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| {

View file

@ -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 {

View file

@ -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]);
}
}

View file

@ -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;

View file

@ -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();

View file

@ -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)) {

View file

@ -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),

View file

@ -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
}

View file

@ -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

View file

@ -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),
}
}

View file

@ -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

View file

@ -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 {

View file

@ -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) {

View file

@ -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,

View file

@ -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!(

View file

@ -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);
}

View file

@ -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))
})

View file

@ -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;

View file

@ -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();

View file

@ -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,

View file

@ -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,

View file

@ -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 {

View file

@ -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('{');

View file

@ -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,

View file

@ -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;

View file

@ -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);
}
}
}

View file

@ -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));
}
}

View file

@ -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

View file

@ -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, &[]))
}

View file

@ -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 {

View file

@ -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> {

View file

@ -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);
}
}

View file

@ -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()"),
];
}

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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""#);

View file

@ -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];

View file

@ -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));
}
}

View file

@ -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);

View file

@ -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(

View file

@ -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;
}
}

View file

@ -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!(

View file

@ -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,

View file

@ -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 {

View file

@ -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))

View file

@ -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;

View file

@ -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,

View file

@ -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)
}

View file

@ -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"];

View file

@ -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;

View file

@ -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: "",
}

View file

@ -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;