mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-27 07:00:55 +00:00
Various cosmetic improvements.
This commit is contained in:
parent
016d92d6ed
commit
d43966a176
73 changed files with 510 additions and 470 deletions
|
@ -191,7 +191,7 @@ pub struct FileChange {
|
|||
pub new_lines: String,
|
||||
}
|
||||
|
||||
/// Replace a region in a file delimited by two lines matching regexes.
|
||||
/// Replaces a region in a file delimited by two lines matching regexes.
|
||||
///
|
||||
/// `path` is the relative path to the file on which you want to perform the replacement.
|
||||
///
|
||||
|
@ -225,7 +225,7 @@ where
|
|||
file_change
|
||||
}
|
||||
|
||||
/// Replace a region in a text delimited by two lines matching regexes.
|
||||
/// Replaces a region in a text delimited by two lines matching regexes.
|
||||
///
|
||||
/// * `text` is the input text on which you want to perform the replacement
|
||||
/// * `start` is a `&str` that describes the delimiter line before the region you want to replace.
|
||||
|
|
|
@ -104,7 +104,7 @@ fn check_known_consts(cx: &LateContext<'_, '_>, e: &Expr, s: symbol::Symbol, mod
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns false if the number of significant figures in `value` are
|
||||
/// Returns `false` if the number of significant figures in `value` are
|
||||
/// less than `min_digits`; otherwise, returns true if `value` is equal
|
||||
/// to `constant`, rounded to the number of digits present in `value`.
|
||||
fn is_approx_const(constant: f64, value: &str, min_digits: usize) -> bool {
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
use if_chain::if_chain;
|
||||
use rustc::hir::{Expr, ExprKind};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
||||
use crate::consts::{constant, Constant};
|
||||
use crate::rustc::hir::{Expr, ExprKind};
|
||||
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use crate::rustc::{declare_tool_lint, lint_array};
|
||||
use crate::syntax::ast::LitKind;
|
||||
use crate::utils::{in_macro, is_direct_expn_of, span_help_and_lint};
|
||||
use if_chain::if_chain;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Check to call assert!(true/false)
|
||||
/// **What it does:** Checks for `assert!(true)` and `assert!(false)` calls.
|
||||
///
|
||||
/// **Why is this bad?** Will be optimized out by the compiler or should probably be replaced by a
|
||||
/// panic!() or unreachable!()
|
||||
|
@ -15,17 +16,18 @@ declare_clippy_lint! {
|
|||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```no_run
|
||||
/// assert!(false);
|
||||
/// ```rust
|
||||
/// assert!(false)
|
||||
/// // or
|
||||
/// assert!(true);
|
||||
/// assert!(true)
|
||||
/// // or
|
||||
/// const B: bool = false;
|
||||
/// assert!(B);
|
||||
/// assert!(B)
|
||||
/// ```
|
||||
pub ASSERTIONS_ON_CONSTANTS,
|
||||
style,
|
||||
"assert!(true/false) will be optimized out by the compiler/should probably be replaced by a panic!() or unreachable!()"
|
||||
"`assert!(true)` / `assert!(false)` will be optimized out by the compiler, \
|
||||
and should probably be replaced by a `panic!()` or `unreachable!()`"
|
||||
}
|
||||
|
||||
pub struct AssertionsOnConstants;
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
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 if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc::hir;
|
||||
use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
|
||||
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};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `a = a op b` or `a = b commutative_op a`
|
||||
|
@ -19,7 +21,7 @@ declare_clippy_lint! {
|
|||
/// implementations that differ from the regular `Op` impl.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// ```rust
|
||||
/// let mut a = 5;
|
||||
/// ...
|
||||
/// a = a + b;
|
||||
|
@ -36,12 +38,12 @@ declare_clippy_lint! {
|
|||
/// op= b`.
|
||||
///
|
||||
/// **Known problems:** Clippy cannot know for sure if `a op= a op b` should have
|
||||
/// been `a = a op a op b` or `a = a op b`/`a op= b`. Therefore it suggests both.
|
||||
/// been `a = a op a op b` or `a = a op b`/`a op= b`. Therefore, it suggests both.
|
||||
/// If `a op= a op b` is really the correct behaviour it should be
|
||||
/// written as `a = a op a op b` as it's less confusing.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// ```rust
|
||||
/// let mut a = 5;
|
||||
/// ...
|
||||
/// a += a + b;
|
||||
|
|
|
@ -70,7 +70,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub INEFFECTIVE_BIT_MASK,
|
||||
correctness,
|
||||
"expressions where a bit mask will be rendered useless by a comparison, e.g. `(x | 1) > 2`"
|
||||
"expressions where a bit mask will be rendered useless by a comparison, e.g., `(x | 1) > 2`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
|
|
@ -20,7 +20,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub BLOCK_IN_IF_CONDITION_EXPR,
|
||||
style,
|
||||
"braces that can be eliminated in conditions, e.g. `if { true } ...`"
|
||||
"braces that can be eliminated in conditions, e.g., `if { true } ...`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -39,7 +39,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub BLOCK_IN_IF_CONDITION_STMT,
|
||||
style,
|
||||
"complex blocks in conditions, e.g. `if { let x = true; x } ...`"
|
||||
"complex blocks in conditions, e.g., `if { let x = true; x } ...`"
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
|
|
@ -68,7 +68,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub COLLAPSIBLE_IF,
|
||||
style,
|
||||
"`if`s that can be collapsed (e.g. `if x { if y { ... } }` and `else { if x { ... } }`)"
|
||||
"`if`s that can be collapsed (e.g., `if x { if y { ... } }` and `else { if x { ... } }`)"
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
|
|
@ -21,27 +21,27 @@ use syntax_pos::symbol::Symbol;
|
|||
/// A `LitKind`-like enum to fold constant `Expr`s into.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Constant {
|
||||
/// a String "abc"
|
||||
/// A `String` (e.g., "abc").
|
||||
Str(String),
|
||||
/// a Binary String b"abc"
|
||||
/// A binary string (e.g., `b"abc"`).
|
||||
Binary(Lrc<Vec<u8>>),
|
||||
/// a single char 'a'
|
||||
/// A single `char` (e.g., `'a'`).
|
||||
Char(char),
|
||||
/// an integer's bit representation
|
||||
/// An integer's bit representation.
|
||||
Int(u128),
|
||||
/// an f32
|
||||
/// An `f32`.
|
||||
F32(f32),
|
||||
/// an f64
|
||||
/// An `f64`.
|
||||
F64(f64),
|
||||
/// true or false
|
||||
/// `true` or `false`.
|
||||
Bool(bool),
|
||||
/// an array of constants
|
||||
/// An array of constants.
|
||||
Vec(Vec<Constant>),
|
||||
/// also an array, but with only one constant, repeated N times
|
||||
/// Also an array, but with only one constant, repeated N times.
|
||||
Repeat(Box<Constant>, u64),
|
||||
/// a tuple of constants
|
||||
/// A tuple of constants.
|
||||
Tuple(Vec<Constant>),
|
||||
/// a literal with syntax error
|
||||
/// A literal with syntax error.
|
||||
Err(Symbol),
|
||||
}
|
||||
|
||||
|
@ -53,15 +53,15 @@ impl PartialEq for Constant {
|
|||
(&Constant::Char(l), &Constant::Char(r)) => l == r,
|
||||
(&Constant::Int(l), &Constant::Int(r)) => l == r,
|
||||
(&Constant::F64(l), &Constant::F64(r)) => {
|
||||
// we want `Fw32 == FwAny` and `FwAny == Fw64`, by transitivity we must have
|
||||
// `Fw32 == Fw64` so don’t compare them
|
||||
// to_bits is required to catch non-matching 0.0, -0.0, and NaNs
|
||||
// We want `Fw32 == FwAny` and `FwAny == Fw64`, and by transitivity we must have
|
||||
// `Fw32 == Fw64`, so don’t compare them.
|
||||
// `to_bits` is required to catch non-matching 0.0, -0.0, and NaNs.
|
||||
l.to_bits() == r.to_bits()
|
||||
},
|
||||
(&Constant::F32(l), &Constant::F32(r)) => {
|
||||
// we want `Fw32 == FwAny` and `FwAny == Fw64`, by transitivity we must have
|
||||
// `Fw32 == Fw64` so don’t compare them
|
||||
// to_bits is required to catch non-matching 0.0, -0.0, and NaNs
|
||||
// We want `Fw32 == FwAny` and `FwAny == Fw64`, and by transitivity we must have
|
||||
// `Fw32 == Fw64`, so don’t compare them.
|
||||
// `to_bits` is required to catch non-matching 0.0, -0.0, and NaNs.
|
||||
f64::from(l).to_bits() == f64::from(r).to_bits()
|
||||
},
|
||||
(&Constant::Bool(l), &Constant::Bool(r)) => l == r,
|
||||
|
@ -69,7 +69,8 @@ impl PartialEq for Constant {
|
|||
l == r
|
||||
},
|
||||
(&Constant::Repeat(ref lv, ref ls), &Constant::Repeat(ref rv, ref rs)) => ls == rs && lv == rv,
|
||||
_ => false, // TODO: Are there inter-type equalities?
|
||||
// TODO: are there inter-type equalities?
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,12 +143,13 @@ impl Constant {
|
|||
x => x,
|
||||
}
|
||||
},
|
||||
_ => None, // TODO: Are there any useful inter-type orderings?
|
||||
// TODO: are there any useful inter-type orderings?
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// parse a `LitKind` to a `Constant`
|
||||
/// Parses a `LitKind` to a `Constant`.
|
||||
pub fn lit_to_constant<'tcx>(lit: &LitKind, ty: Ty<'tcx>) -> Constant {
|
||||
use syntax::ast::*;
|
||||
|
||||
|
|
|
@ -239,9 +239,9 @@ fn lint_match_arms(cx: &LateContext<'_, '_>, expr: &Expr) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return the list of condition expressions and the list of blocks in a
|
||||
/// Returns the list of condition expressions and the list of blocks in a
|
||||
/// sequence of `if/else`.
|
||||
/// Eg. would return `([a, b], [c, d, e])` for the expression
|
||||
/// E.g., this returns `([a, b], [c, d, e])` for the expression
|
||||
/// `if a { c } else if b { d } else { e }`.
|
||||
fn if_sequence(mut expr: &Expr) -> (SmallVec<[&Expr; 1]>, SmallVec<[&Block; 1]>) {
|
||||
let mut conds = SmallVec::new();
|
||||
|
@ -272,7 +272,7 @@ fn if_sequence(mut expr: &Expr) -> (SmallVec<[&Expr; 1]>, SmallVec<[&Block; 1]>)
|
|||
(conds, blocks)
|
||||
}
|
||||
|
||||
/// Return the list of bindings in a pattern.
|
||||
/// Returns the list of bindings in a pattern.
|
||||
fn bindings<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat) -> FxHashMap<LocalInternedString, Ty<'tcx>> {
|
||||
fn bindings_impl<'a, 'tcx>(
|
||||
cx: &LateContext<'a, 'tcx>,
|
||||
|
|
|
@ -90,7 +90,7 @@ declare_deprecated_lint! {
|
|||
/// counterparts, so this lint may suggest a change in behavior or the code may not compile.
|
||||
declare_deprecated_lint! {
|
||||
pub ASSIGN_OPS,
|
||||
"using compound assignment operators (e.g. `+=`) is harmless"
|
||||
"using compound assignment operators (e.g., `+=`) is harmless"
|
||||
}
|
||||
|
||||
/// **What it does:** Nothing. This lint has been deprecated.
|
||||
|
|
|
@ -257,8 +257,8 @@ fn check_text(cx: &EarlyContext<'_>, valid_idents: &FxHashSet<String>, text: &st
|
|||
}
|
||||
|
||||
fn check_word(cx: &EarlyContext<'_>, word: &str, span: Span) {
|
||||
/// Checks if a string is camel-case, ie. contains at least two uppercase
|
||||
/// letter (`Clippy` is
|
||||
/// Checks if a string is camel-case, i.e., contains at least two uppercase
|
||||
/// letters (`Clippy` is
|
||||
/// ok) and one lower-case letter (`NASA` is ok). Plural are also excluded
|
||||
/// (`IDs` is ok).
|
||||
fn is_camel_case(s: &str) -> bool {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//! lint on if expressions with an else if, but without a final else branch
|
||||
//! Lint on if expressions with an else if, but without a final else branch.
|
||||
|
||||
use rustc::lint::{in_external_macro, EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
@ -10,7 +10,7 @@ declare_clippy_lint! {
|
|||
/// **What it does:** Checks for usage of if expressions with an `else if` branch,
|
||||
/// but without a final `else` branch.
|
||||
///
|
||||
/// **Why is this bad?** Some coding guidelines require this (e.g. MISRA-C:2004 Rule 14.10).
|
||||
/// **Why is this bad?** Some coding guidelines require this (e.g., MISRA-C:2004 Rule 14.10).
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
|
@ -31,7 +31,7 @@ declare_clippy_lint! {
|
|||
/// } else if x.is_negative() {
|
||||
/// b();
|
||||
/// } else {
|
||||
/// // we don't care about zero
|
||||
/// // We don't care about zero.
|
||||
/// }
|
||||
/// ```
|
||||
pub ELSE_IF_WITHOUT_ELSE,
|
||||
|
|
|
@ -24,7 +24,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub EQ_OP,
|
||||
correctness,
|
||||
"equal operands on both sides of a comparison or bitwise combination (e.g. `x == x`)"
|
||||
"equal operands on both sides of a comparison or bitwise combination (e.g., `x == x`)"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use crate::consts::{constant_simple, Constant};
|
||||
use crate::utils::{in_macro, span_lint};
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::source_map::Span;
|
||||
|
||||
use crate::consts::{constant_simple, Constant};
|
||||
use crate::utils::{in_macro, span_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for erasing operations, e.g. `x * 0`.
|
||||
/// **What it does:** Checks for erasing operations, e.g., `x * 0`.
|
||||
///
|
||||
/// **Why is this bad?** The whole expression can be replaced by zero.
|
||||
/// This is most likely not the intended outcome and should probably be
|
||||
|
@ -15,14 +16,14 @@ declare_clippy_lint! {
|
|||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// ```rust
|
||||
/// 0 / x;
|
||||
/// 0 * x;
|
||||
/// x & 0
|
||||
/// ```
|
||||
pub ERASING_OP,
|
||||
correctness,
|
||||
"using erasing operations, e.g. `x * 0` or `y & 0`"
|
||||
"using erasing operations, e.g., `x * 0` or `y & 0`"
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::utils::span_lint;
|
||||
use rustc::hir::intravisit as visit;
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
|
@ -10,6 +9,8 @@ use rustc::util::nodemap::HirIdSet;
|
|||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::source_map::Span;
|
||||
|
||||
use crate::utils::span_lint;
|
||||
|
||||
pub struct Pass {
|
||||
pub too_large_for_stack: u64,
|
||||
}
|
||||
|
@ -67,7 +68,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
_: Span,
|
||||
hir_id: HirId,
|
||||
) {
|
||||
// If the method is an impl for a trait, don't warn
|
||||
// If the method is an impl for a trait, don't warn.
|
||||
let parent_id = cx.tcx.hir().get_parent_item(hir_id);
|
||||
let parent_node = cx.tcx.hir().find_by_hir_id(parent_id);
|
||||
|
||||
|
@ -102,7 +103,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
|
|||
fn consume(&mut self, _: HirId, _: Span, cmt: &cmt_<'tcx>, mode: ConsumeMode) {
|
||||
if let Categorization::Local(lid) = cmt.cat {
|
||||
if let Move(DirectRefMove) = mode {
|
||||
// moved out or in. clearly can't be localized
|
||||
// Moved out or in. Clearly can't be localized.
|
||||
self.set.remove(&lid);
|
||||
}
|
||||
}
|
||||
|
@ -158,20 +159,20 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
|
|||
) {
|
||||
if let Categorization::Local(lid) = cmt.cat {
|
||||
match loan_cause {
|
||||
// x.foo()
|
||||
// Used without autodereffing (i.e. x.clone())
|
||||
// `x.foo()`
|
||||
// Used without autoderef-ing (i.e., `x.clone()`).
|
||||
LoanCause::AutoRef |
|
||||
|
||||
// &x
|
||||
// foo(&x) where no extra autoreffing is happening
|
||||
// `&x`
|
||||
// `foo(&x)` where no extra autoref-ing is happening.
|
||||
LoanCause::AddrOf |
|
||||
|
||||
// `match x` can move
|
||||
// `match x` can move.
|
||||
LoanCause::MatchDiscriminant => {
|
||||
self.set.remove(&lid);
|
||||
}
|
||||
|
||||
// do nothing for matches, etc. These can't escape
|
||||
// Do nothing for matches, etc. These can't escape.
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -182,8 +183,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
|
|||
|
||||
impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {
|
||||
fn is_large_box(&self, ty: Ty<'tcx>) -> bool {
|
||||
// Large types need to be boxed to avoid stack
|
||||
// overflows.
|
||||
// Large types need to be boxed to avoid stack overflows.
|
||||
if ty.is_box() {
|
||||
self.cx.layout_of(ty.boxed_ty()).ok().map_or(0, |l| l.size.bytes()) > self.too_large_for_stack
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::utils::{is_adjusted, iter_input_pats, snippet_opt, span_lint_and_then, type_is_unsafe_function};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::{in_external_macro, LateContext, LateLintPass, LintArray, LintContext, LintPass};
|
||||
|
@ -6,6 +5,8 @@ use rustc::ty;
|
|||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
|
||||
use crate::utils::{is_adjusted, iter_input_pats, snippet_opt, span_lint_and_then, type_is_unsafe_function};
|
||||
|
||||
pub struct EtaPass;
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -19,18 +20,17 @@ declare_clippy_lint! {
|
|||
/// **Known problems:** If creating the closure inside the closure has a side-
|
||||
/// effect then moving the closure creation out will change when that side-
|
||||
/// effect runs.
|
||||
/// See https://github.com/rust-lang/rust-clippy/issues/1439 for more
|
||||
/// details.
|
||||
/// See rust-lang/rust-clippy#1439 for more details.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// ```rust
|
||||
/// xs.map(|x| foo(x))
|
||||
/// ```
|
||||
/// where `foo(_)` is a plain function that takes the exact argument type of
|
||||
/// `x`.
|
||||
pub REDUNDANT_CLOSURE,
|
||||
style,
|
||||
"redundant closures, i.e. `|a| foo(a)` (which can be written as just `foo`)"
|
||||
"redundant closures, i.e., `|a| foo(a)` (which can be written as just `foo`)"
|
||||
}
|
||||
|
||||
impl LintPass for EtaPass {
|
||||
|
|
|
@ -286,7 +286,7 @@ fn check_stmt<'a, 'tcx>(vis: &mut ReadVisitor<'a, 'tcx>, stmt: &'tcx Stmt) -> St
|
|||
/// A visitor that looks for reads from a variable.
|
||||
struct ReadVisitor<'a, 'tcx: 'a> {
|
||||
cx: &'a LateContext<'a, 'tcx>,
|
||||
/// The id of the variable we're looking for.
|
||||
/// The ID of the variable we're looking for.
|
||||
var: ast::NodeId,
|
||||
/// The expressions where the write to the variable occurred (for reporting
|
||||
/// in the lint).
|
||||
|
@ -351,7 +351,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns true if `expr` is the LHS of an assignment, like `expr = ...`.
|
||||
/// Returns `true` if `expr` is the LHS of an assignment, like `expr = ...`.
|
||||
fn is_in_assignment_position(cx: &LateContext<'_, '_>, expr: &Expr) -> bool {
|
||||
if let Some(parent) = get_parent_expr(cx, expr) {
|
||||
if let ExprKind::Assign(ref lhs, _) = parent.node {
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
use crate::consts::{constant_simple, Constant};
|
||||
use crate::utils::{clip, in_macro, snippet, span_lint, unsext};
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::ty;
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::source_map::Span;
|
||||
|
||||
use crate::consts::{constant_simple, Constant};
|
||||
use crate::utils::{clip, in_macro, snippet, span_lint, unsext};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for identity operations, e.g. `x + 0`.
|
||||
/// **What it does:** Checks for identity operations, e.g., `x + 0`.
|
||||
///
|
||||
/// **Why is this bad?** This code can be removed without changing the
|
||||
/// meaning. So it just obscures what's going on. Delete it mercilessly.
|
||||
|
@ -20,7 +21,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub IDENTITY_OP,
|
||||
complexity,
|
||||
"using identity operations, e.g. `x + 0` or `y / 1`"
|
||||
"using identity operations, e.g., `x + 0` or `y / 1`"
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
|
|
@ -103,7 +103,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing {
|
|||
if let ExprKind::Index(ref array, ref index) = &expr.node {
|
||||
let ty = cx.tables.expr_ty(array);
|
||||
if let Some(range) = higher::range(cx, index) {
|
||||
// Ranged indexes, i.e. &x[n..m], &x[n..], &x[..n] and &x[..]
|
||||
// Ranged indexes, i.e., &x[n..m], &x[n..], &x[..n] and &x[..]
|
||||
if let ty::Array(_, s) = ty.sty {
|
||||
let size: u128 = s.assert_usize(cx.tcx).unwrap().into();
|
||||
|
||||
|
@ -149,7 +149,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing {
|
|||
|
||||
utils::span_help_and_lint(cx, INDEXING_SLICING, expr.span, "slicing may panic.", help_msg);
|
||||
} else {
|
||||
// Catchall non-range index, i.e. [n] or [n << m]
|
||||
// Catchall non-range index, i.e., [n] or [n << m]
|
||||
if let ty::Array(..) = ty.sty {
|
||||
// Index is a constant uint.
|
||||
if let Some(..) = constant(cx, cx.tables, index) {
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
use crate::utils::{get_trait_def_id, higher, implements_trait, match_qpath, match_type, paths, span_lint};
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
||||
use crate::utils::{get_trait_def_id, higher, implements_trait, match_qpath, match_type, paths, span_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for iteration that is guaranteed to be infinite.
|
||||
///
|
||||
/// **Why is this bad?** While there may be places where this is acceptable
|
||||
/// (e.g. in event streams), in most cases this is simply an error.
|
||||
/// (e.g., in event streams), in most cases this is simply an error.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
|
@ -26,7 +27,7 @@ declare_clippy_lint! {
|
|||
/// **What it does:** Checks for iteration that may be infinite.
|
||||
///
|
||||
/// **Why is this bad?** While there may be places where this is acceptable
|
||||
/// (e.g. in event streams), in most cases this is simply an error.
|
||||
/// (e.g., in event streams), in most cases this is simply an error.
|
||||
///
|
||||
/// **Known problems:** The code may have a condition to stop iteration, but
|
||||
/// this lint is not clever enough to analyze it.
|
||||
|
@ -122,8 +123,8 @@ use self::Heuristic::{All, Always, Any, First};
|
|||
/// 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`.
|
||||
/// is an upper bound, e.g., some methods can return a possibly
|
||||
/// infinite iterator at worst, e.g., `take_while`.
|
||||
static HEURISTICS: &[(&str, usize, Heuristic, Finiteness)] = &[
|
||||
("zip", 2, All, Infinite),
|
||||
("chain", 2, Any, Infinite),
|
||||
|
|
|
@ -274,9 +274,9 @@ fn check_len(
|
|||
}
|
||||
}
|
||||
|
||||
/// Check if this type has an `is_empty` method.
|
||||
/// Checks if this type has an `is_empty` method.
|
||||
fn has_is_empty(cx: &LateContext<'_, '_>, expr: &Expr) -> bool {
|
||||
/// Get an `AssociatedItem` and return true if it matches `is_empty(self)`.
|
||||
/// 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 == "is_empty" {
|
||||
|
@ -291,7 +291,7 @@ fn has_is_empty(cx: &LateContext<'_, '_>, expr: &Expr) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
/// Check the inherent impl's items for an `is_empty(self)` method.
|
||||
/// Checks the inherent impl's items for an `is_empty(self)` method.
|
||||
fn has_is_empty_impl(cx: &LateContext<'_, '_>, id: DefId) -> bool {
|
||||
cx.tcx
|
||||
.inherent_impls(id)
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#![feature(crate_visibility_modifier)]
|
||||
|
||||
// FIXME: switch to something more ergonomic here, once available.
|
||||
// (currently there is no way to opt into sysroot crates w/o `extern crate`)
|
||||
// (Currently there is no way to opt into sysroot crates without `extern crate`.)
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate fmt_macros;
|
||||
#[allow(unused_extern_crates)]
|
||||
|
@ -407,7 +407,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||
);
|
||||
store.register_removed(
|
||||
"assign_ops",
|
||||
"using compound assignment operators (e.g. `+=`) is harmless",
|
||||
"using compound assignment operators (e.g., `+=`) is harmless",
|
||||
);
|
||||
store.register_removed(
|
||||
"if_let_redundant_pattern_matching",
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use crate::reexport::*;
|
||||
use crate::utils::{last_path_segment, span_lint};
|
||||
use matches::matches;
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::intravisit::*;
|
||||
|
@ -10,6 +8,9 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
|||
use syntax::source_map::Span;
|
||||
use syntax::symbol::keywords;
|
||||
|
||||
use crate::reexport::*;
|
||||
use crate::utils::{last_path_segment, span_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for lifetime annotations which can be removed by
|
||||
/// relying on lifetime elision.
|
||||
|
@ -19,7 +20,7 @@ declare_clippy_lint! {
|
|||
/// them leads to more readable code.
|
||||
///
|
||||
/// **Known problems:** Potential false negatives: we bail out if the function
|
||||
/// has a `where` clause where lifetimes are mentioned.
|
||||
/// has a where-clause where lifetimes are mentioned.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
|
@ -384,7 +385,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Are any lifetimes mentioned in the `where` clause? If yes, we don't try to
|
||||
/// Are any lifetimes mentioned in the where-clause? If yes, we don't try to
|
||||
/// reason about elision.
|
||||
fn has_where_lifetimes<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, where_clause: &'tcx WhereClause) -> bool {
|
||||
for predicate in &where_clause.predicates {
|
||||
|
|
|
@ -112,7 +112,7 @@ pub(super) enum Radix {
|
|||
}
|
||||
|
||||
impl Radix {
|
||||
/// Return a reasonable digit group size for this radix.
|
||||
/// Returns a reasonable digit group size for this radix.
|
||||
crate fn suggest_grouping(&self) -> usize {
|
||||
match *self {
|
||||
Radix::Binary | Radix::Hexadecimal => 4,
|
||||
|
|
|
@ -727,7 +727,7 @@ fn never_loop_expr(expr: &Expr, main_loop_id: HirId) -> NeverLoopResult {
|
|||
ExprKind::Continue(d) => {
|
||||
let id = d
|
||||
.target_id
|
||||
.expect("target id can only be missing in the presence of compilation errors");
|
||||
.expect("target ID can only be missing in the presence of compilation errors");
|
||||
if id == main_loop_id {
|
||||
NeverLoopResult::MayContinueMainLoop
|
||||
} else {
|
||||
|
@ -953,7 +953,7 @@ fn get_indexed_assignments<'a, 'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
/// Check for for loops that sequentially copy items from one slice-like
|
||||
/// Checks for for loops that sequentially copy items from one slice-like
|
||||
/// object to another.
|
||||
fn detect_manual_memcpy<'a, 'tcx>(
|
||||
cx: &LateContext<'a, 'tcx>,
|
||||
|
@ -1065,7 +1065,7 @@ fn detect_manual_memcpy<'a, 'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
/// Check for looping over a range and then indexing a sequence with it.
|
||||
/// Checks for looping over a range and then indexing a sequence with it.
|
||||
/// The iteratee must be a range literal.
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn check_for_loop_range<'a, 'tcx>(
|
||||
|
@ -1413,7 +1413,7 @@ fn check_for_loop_arg(cx: &LateContext<'_, '_>, pat: &Pat, arg: &Expr, expr: &Ex
|
|||
}
|
||||
}
|
||||
|
||||
/// Check for `for` loops over `Option`s and `Results`
|
||||
/// Checks for `for` loops over `Option`s and `Results`
|
||||
fn check_arg_type(cx: &LateContext<'_, '_>, pat: &Pat, arg: &Expr) {
|
||||
let ty = cx.tables.expr_ty(arg);
|
||||
if match_type(cx, ty, &paths::OPTION) {
|
||||
|
@ -1507,7 +1507,7 @@ fn check_for_loop_explicit_counter<'a, 'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
/// Check for the `FOR_KV_MAP` lint.
|
||||
/// Checks for the `FOR_KV_MAP` lint.
|
||||
fn check_for_loop_over_map_kv<'a, 'tcx>(
|
||||
cx: &LateContext<'a, 'tcx>,
|
||||
pat: &'tcx Pat,
|
||||
|
@ -1673,7 +1673,7 @@ fn check_for_mutation(
|
|||
delegate.mutation_span()
|
||||
}
|
||||
|
||||
/// Return true if the pattern is a `PatWild` or an ident prefixed with `'_'`.
|
||||
/// Returns `true` if the pattern is a `PatWild` or an ident prefixed with `'_'`.
|
||||
fn pat_is_wild<'tcx>(pat: &'tcx PatKind, body: &'tcx Expr) -> bool {
|
||||
match *pat {
|
||||
PatKind::Wild => true,
|
||||
|
@ -1967,7 +1967,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarUsedAfterLoopVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return true if the type of expr is one that provides `IntoIterator` impls
|
||||
/// Returns `true` if the type of expr is one that provides `IntoIterator` impls
|
||||
/// for `&T` and `&mut T`, such as `Vec`.
|
||||
#[rustfmt::skip]
|
||||
fn is_ref_iterable_type(cx: &LateContext<'_, '_>, e: &Expr) -> bool {
|
||||
|
@ -2022,7 +2022,7 @@ fn extract_first_expr(block: &Block) -> Option<&Expr> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return true if expr contains a single break expr without destination label
|
||||
/// Returns `true` if expr contains a single break expr without destination label
|
||||
/// and
|
||||
/// passed expression. The expression may be within a block.
|
||||
fn is_simple_break_expr(expr: &Expr) -> bool {
|
||||
|
@ -2102,7 +2102,7 @@ impl<'a, 'tcx> Visitor<'tcx> for IncrementVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Check whether a variable is initialized to zero at the start of a loop.
|
||||
/// Checks whether a variable is initialized to zero at the start of a loop.
|
||||
struct InitializeVisitor<'a, 'tcx: 'a> {
|
||||
cx: &'a LateContext<'a, 'tcx>, // context reference
|
||||
end_expr: &'tcx Expr, // the for loop. Stop scanning here.
|
||||
|
@ -2336,7 +2336,7 @@ fn path_name(e: &Expr) -> Option<Name> {
|
|||
|
||||
fn check_infinite_loop<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, cond: &'tcx Expr, expr: &'tcx Expr) {
|
||||
if constant(cx, cx.tables, cond).is_some() {
|
||||
// A pure constant condition (e.g. while false) is not linted.
|
||||
// A pure constant condition (e.g., while false) is not linted.
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub SINGLE_MATCH,
|
||||
style,
|
||||
"a match statement with a single nontrivial arm (i.e. where the other arm is `_ => {}`) instead of `if let`"
|
||||
"a match statement with a single nontrivial arm (i.e., where the other arm is `_ => {}`) instead of `if let`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -335,7 +335,7 @@ fn check_single_match_opt_like(
|
|||
|
||||
let path = match arms[1].pats[0].node {
|
||||
PatKind::TupleStruct(ref path, ref inner, _) => {
|
||||
// contains any non wildcard patterns? e.g. Err(err)
|
||||
// contains any non wildcard patterns? e.g., Err(err)
|
||||
if !inner.iter().all(is_wild) {
|
||||
return;
|
||||
}
|
||||
|
@ -639,7 +639,7 @@ fn check_match_as_ref(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &
|
|||
}
|
||||
}
|
||||
|
||||
/// Get all arms that are unbounded `PatRange`s.
|
||||
/// Gets all arms that are unbounded `PatRange`s.
|
||||
fn all_ranges<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arms: &'tcx [Arm]) -> Vec<SpannedRange<Constant>> {
|
||||
arms.iter()
|
||||
.flat_map(|arm| {
|
||||
|
@ -687,7 +687,7 @@ pub struct SpannedRange<T> {
|
|||
|
||||
type TypedRanges = Vec<SpannedRange<u128>>;
|
||||
|
||||
/// Get all `Int` ranges or all `Uint` ranges. Mixed types are an error anyway
|
||||
/// Gets all `Int` ranges or all `Uint` ranges. Mixed types are an error anyway
|
||||
/// and other types than
|
||||
/// `Uint` and `Int` probably don't make sense.
|
||||
fn type_ranges(ranges: &[SpannedRange<Constant>]) -> TypedRanges {
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
mod option_map_unwrap_or;
|
||||
mod unnecessary_filter_map;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::iter;
|
||||
|
||||
use if_chain::if_chain;
|
||||
use matches::matches;
|
||||
use rustc::hir;
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::lint::{in_external_macro, LateContext, LateLintPass, Lint, LintArray, LintContext, LintPass};
|
||||
use rustc::ty::{self, Predicate, Ty};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
use syntax::ast;
|
||||
use syntax::source_map::{BytePos, Span};
|
||||
use syntax::symbol::LocalInternedString;
|
||||
|
||||
use crate::utils::paths;
|
||||
use crate::utils::sugg;
|
||||
use crate::utils::{
|
||||
|
@ -7,23 +26,6 @@ use crate::utils::{
|
|||
single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint,
|
||||
span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq,
|
||||
};
|
||||
use if_chain::if_chain;
|
||||
use matches::matches;
|
||||
use rustc::hir;
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::lint::{in_external_macro, LateContext, LateLintPass, Lint, LintArray, LintContext, LintPass};
|
||||
use rustc::ty::{self, Predicate, Ty};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::iter;
|
||||
use syntax::ast;
|
||||
use syntax::source_map::{BytePos, Span};
|
||||
use syntax::symbol::LocalInternedString;
|
||||
|
||||
mod option_map_unwrap_or;
|
||||
mod unnecessary_filter_map;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Pass;
|
||||
|
@ -55,7 +57,7 @@ declare_clippy_lint! {
|
|||
/// and propagate errors upwards with `try!`.
|
||||
///
|
||||
/// Even if you want to panic on errors, not all `Error`s implement good
|
||||
/// messages on display. Therefore it may be beneficial to look at the places
|
||||
/// messages on display. Therefore, it may be beneficial to look at the places
|
||||
/// where they may get displayed. Activate this lint to do just that.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
|
@ -399,7 +401,7 @@ declare_clippy_lint! {
|
|||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of `.clone()` on a ref-counted pointer,
|
||||
/// (`Rc`, `Arc`, `rc::Weak`, or `sync::Weak`), and suggests calling Clone via unified
|
||||
/// function syntax instead (e.g. `Rc::clone(foo)`).
|
||||
/// function syntax instead (e.g., `Rc::clone(foo)`).
|
||||
///
|
||||
/// **Why is this bad?** Calling '.clone()' on an Rc, Arc, or Weak
|
||||
/// can obscure the fact that only the pointer is being cloned, not the underlying
|
||||
|
@ -458,7 +460,7 @@ declare_clippy_lint! {
|
|||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for string methods that receive a single-character
|
||||
/// `str` as an argument, e.g. `_.split("x")`.
|
||||
/// `str` as an argument, e.g., `_.split("x")`.
|
||||
///
|
||||
/// **Why is this bad?** Performing these methods using a `char` is faster than
|
||||
/// using a `str`.
|
||||
|
@ -469,7 +471,7 @@ declare_clippy_lint! {
|
|||
/// `_.split("x")` could be `_.split('x')`
|
||||
pub SINGLE_CHAR_PATTERN,
|
||||
perf,
|
||||
"using a single-character str where a char could be used, e.g. `_.split(\"x\")`"
|
||||
"using a single-character str where a char could be used, e.g., `_.split(\"x\")`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -1008,7 +1010,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
/// Checks for the `OR_FUN_CALL` lint.
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn lint_or_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: Span, name: &str, args: &[hir::Expr]) {
|
||||
/// Check for `unwrap_or(T::new())` or `unwrap_or(T::default())`.
|
||||
/// Checks for `unwrap_or(T::new())` or `unwrap_or(T::default())`.
|
||||
fn check_unwrap_or_default(
|
||||
cx: &LateContext<'_, '_>,
|
||||
name: &str,
|
||||
|
@ -1057,7 +1059,7 @@ fn lint_or_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: Spa
|
|||
false
|
||||
}
|
||||
|
||||
/// Check for `*or(foo())`.
|
||||
/// Checks for `*or(foo())`.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn check_general_case(
|
||||
cx: &LateContext<'_, '_>,
|
||||
|
@ -1546,7 +1548,7 @@ fn lint_unnecessary_fold(cx: &LateContext<'_, '_>, expr: &hir::Expr, fold_args:
|
|||
cx,
|
||||
UNNECESSARY_FOLD,
|
||||
fold_span,
|
||||
// TODO #2371 don't suggest e.g. .any(|x| f(x)) if we can suggest .any(f)
|
||||
// TODO #2371 don't suggest e.g., .any(|x| f(x)) if we can suggest .any(f)
|
||||
"this `.fold` can be written more succinctly using another method",
|
||||
"try",
|
||||
sugg,
|
||||
|
@ -2348,7 +2350,7 @@ impl SelfKind {
|
|||
// Self types in the HIR are desugared to explicit self types. So it will
|
||||
// always be `self:
|
||||
// SomeType`,
|
||||
// where SomeType can be `Self` or an explicit impl self type (e.g. `Foo` if
|
||||
// where SomeType can be `Self` or an explicit impl self type (e.g., `Foo` if
|
||||
// the impl is on `Foo`)
|
||||
// Thus, we only need to test equality against the impl self type or if it is
|
||||
// an explicit
|
||||
|
|
|
@ -1,10 +1,3 @@
|
|||
use crate::consts::{constant, Constant};
|
||||
use crate::utils::sugg::Sugg;
|
||||
use crate::utils::{
|
||||
get_item_name, get_parent_expr, implements_trait, in_constant, in_macro, is_integer_literal, iter_input_pats,
|
||||
last_path_segment, match_qpath, match_trait_method, paths, snippet, span_lint, span_lint_and_then, walk_ptrs_ty,
|
||||
SpanlessEq,
|
||||
};
|
||||
use if_chain::if_chain;
|
||||
use matches::matches;
|
||||
use rustc::hir::intravisit::FnKind;
|
||||
|
@ -16,6 +9,14 @@ use rustc_errors::Applicability;
|
|||
use syntax::ast::LitKind;
|
||||
use syntax::source_map::{ExpnFormat, Span};
|
||||
|
||||
use crate::consts::{constant, Constant};
|
||||
use crate::utils::{
|
||||
get_item_name, get_parent_expr, implements_trait, in_constant, in_macro, is_integer_literal, iter_input_pats,
|
||||
last_path_segment, match_qpath, match_trait_method, paths, snippet, span_lint, span_lint_and_then, walk_ptrs_ty,
|
||||
SpanlessEq,
|
||||
};
|
||||
use crate::utils::sugg::Sugg;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for function arguments and let bindings denoted as
|
||||
/// `ref`.
|
||||
|
@ -31,10 +32,10 @@ declare_clippy_lint! {
|
|||
///
|
||||
/// **Known problems:** If the argument is dereferenced within the function,
|
||||
/// removing the `ref` will lead to errors. This can be fixed by removing the
|
||||
/// dereferences, e.g. changing `*x` to `x` within the function.
|
||||
/// dereferences, e.g., changing `*x` to `x` within the function.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// ```rust
|
||||
/// fn foo(ref x: u8) -> bool {
|
||||
/// ..
|
||||
/// }
|
||||
|
@ -99,7 +100,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub CMP_OWNED,
|
||||
perf,
|
||||
"creating owned instances for comparing with others, e.g. `x == \"foo\".to_string()`"
|
||||
"creating owned instances for comparing with others, e.g., `x == \"foo\".to_string()`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -552,7 +553,7 @@ fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr, other: &Expr) {
|
|||
lint_span,
|
||||
"this creates an owned instance just for comparison",
|
||||
|db| {
|
||||
// this also catches PartialEq implementations that call to_owned
|
||||
// This also catches `PartialEq` implementations that call `to_owned`.
|
||||
if other_gets_derefed {
|
||||
db.span_label(lint_span, "try implementing the comparison without allocating");
|
||||
return;
|
||||
|
@ -590,7 +591,7 @@ fn is_used(cx: &LateContext<'_, '_>, expr: &Expr) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
/// Test whether an expression is in a macro expansion (e.g. something
|
||||
/// Tests whether an expression is in a macro expansion (e.g., something
|
||||
/// generated by
|
||||
/// `#[derive(...)`] or the like).
|
||||
fn in_attributes_expansion(expr: &Expr) -> bool {
|
||||
|
@ -601,7 +602,7 @@ fn in_attributes_expansion(expr: &Expr) -> bool {
|
|||
.map_or(false, |info| matches!(info.format, ExpnFormat::MacroAttribute(_)))
|
||||
}
|
||||
|
||||
/// Test whether `def` is a variable defined outside a macro.
|
||||
/// Tests whether `def` is a variable defined outside a macro.
|
||||
fn non_macro_local(cx: &LateContext<'_, '_>, def: &def::Def) -> bool {
|
||||
match *def {
|
||||
def::Def::Local(id) | def::Def::Upvar(id, _, _) => !in_macro(cx.tcx.hir().span(id)),
|
||||
|
|
|
@ -194,7 +194,7 @@ impl LintPass for MiscEarly {
|
|||
}
|
||||
}
|
||||
|
||||
// Used to find `return` statements or equivalents e.g. `?`
|
||||
// Used to find `return` statements or equivalents e.g., `?`
|
||||
struct ReturnVisitor {
|
||||
found_return: bool,
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub MUT_MUT,
|
||||
pedantic,
|
||||
"usage of double-mut refs, e.g. `&mut &mut ...`"
|
||||
"usage of double-mut refs, e.g., `&mut &mut ...`"
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
|
|
@ -33,7 +33,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub NEEDLESS_BOOL,
|
||||
complexity,
|
||||
"if-statements with plain booleans in the then- and else-clause, e.g. `if p { true } else { false }`"
|
||||
"if-statements with plain booleans in the then- and else-clause, e.g., `if p { true } else { false }`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -51,7 +51,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub BOOL_COMPARISON,
|
||||
complexity,
|
||||
"comparing a variable to a boolean, e.g. `if x == true` or `if x != true`"
|
||||
"comparing a variable to a boolean, e.g., `if x == true` or `if x != true`"
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
|
|
@ -176,7 +176,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
|||
|
||||
//
|
||||
// * Exclude a type that is specifically bounded by `Borrow`.
|
||||
// * Exclude a type whose reference also fulfills its bound. (e.g. `std::convert::AsRef`,
|
||||
// * Exclude a type whose reference also fulfills its bound. (e.g., `std::convert::AsRef`,
|
||||
// `serde::Serialize`)
|
||||
let (implements_borrow_trait, all_borrowable_trait) = {
|
||||
let preds = preds
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::utils::{self, paths, span_lint};
|
|||
declare_clippy_lint! {
|
||||
/// **What it does:**
|
||||
/// Checks for the usage of negated comparison operators on types which only implement
|
||||
/// `PartialOrd` (e.g. `f64`).
|
||||
/// `PartialOrd` (e.g., `f64`).
|
||||
///
|
||||
/// **Why is this bad?**
|
||||
/// These operators make it easy to forget that the underlying types actually allow not only three
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
//! Checks for uses of const which the type is not Freeze (Cell-free).
|
||||
//! Checks for uses of const which the type is not `Freeze` (`Cell`-free).
|
||||
//!
|
||||
//! This lint is **deny** by default.
|
||||
|
||||
use crate::utils::{in_constant, in_macro, is_copy, span_lint_and_then};
|
||||
use std::ptr;
|
||||
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, LateLintPass, Lint, LintArray, LintPass};
|
||||
|
@ -11,14 +12,15 @@ use rustc::ty::{self, TypeFlags};
|
|||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_typeck::hir_ty_to_ty;
|
||||
use std::ptr;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
use crate::utils::{in_constant, in_macro, is_copy, span_lint_and_then};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for declaration of `const` items which is interior
|
||||
/// mutable (e.g. contains a `Cell`, `Mutex`, `AtomicXxxx` etc).
|
||||
/// mutable (e.g., contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.).
|
||||
///
|
||||
/// **Why is this bad?** Consts are copied everywhere they are referenced, i.e.
|
||||
/// **Why is this bad?** Consts are copied everywhere they are referenced, i.e.,
|
||||
/// every time you refer to the const a fresh instance of the `Cell` or `Mutex`
|
||||
/// or `AtomicXxxx` will be created, which defeats the whole purpose of using
|
||||
/// these types in the first place.
|
||||
|
@ -27,7 +29,7 @@ declare_clippy_lint! {
|
|||
/// variable is wanted, or replaced by a `const fn` if a constructor is wanted.
|
||||
///
|
||||
/// **Known problems:** A "non-constant" const item is a legacy way to supply an
|
||||
/// initialized value to downstream `static` items (e.g. the
|
||||
/// initialized value to downstream `static` items (e.g., the
|
||||
/// `std::sync::ONCE_INIT` constant). In this case the use of `const` is legit,
|
||||
/// and this lint should be suppressed.
|
||||
///
|
||||
|
@ -51,10 +53,10 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks if `const` items which is interior mutable (e.g.
|
||||
/// contains a `Cell`, `Mutex`, `AtomicXxxx` etc) has been borrowed directly.
|
||||
/// **What it does:** Checks if `const` items which is interior mutable (e.g.,
|
||||
/// contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.) has been borrowed directly.
|
||||
///
|
||||
/// **Why is this bad?** Consts are copied everywhere they are referenced, i.e.
|
||||
/// **Why is this bad?** Consts are copied everywhere they are referenced, i.e.,
|
||||
/// every time you refer to the const a fresh instance of the `Cell` or `Mutex`
|
||||
/// or `AtomicXxxx` will be created, which defeats the whole purpose of using
|
||||
/// these types in the first place.
|
||||
|
@ -108,8 +110,8 @@ impl Source {
|
|||
|
||||
fn verify_ty_bound<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: ty::Ty<'tcx>, source: Source) {
|
||||
if ty.is_freeze(cx.tcx, cx.param_env, DUMMY_SP) || is_copy(cx, ty) {
|
||||
// an UnsafeCell is !Copy, and an UnsafeCell is also the only type which
|
||||
// is !Freeze, thus if our type is Copy we can be sure it must be Freeze
|
||||
// An `UnsafeCell` is `!Copy`, and an `UnsafeCell` is also the only type which
|
||||
// is `!Freeze`, thus if our type is `Copy` we can be sure it must be `Freeze`
|
||||
// as well.
|
||||
return;
|
||||
}
|
||||
|
@ -179,7 +181,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCopyConst {
|
|||
if let ImplItemKind::Const(hir_ty, ..) = &impl_item.node {
|
||||
let item_hir_id = cx.tcx.hir().get_parent_node_by_hir_id(impl_item.hir_id);
|
||||
let item = cx.tcx.hir().expect_item_by_hir_id(item_hir_id);
|
||||
// ensure the impl is an inherent impl.
|
||||
// Ensure the impl is an inherent impl.
|
||||
if let ItemKind::Impl(_, _, _, _, None, _, _) = item.node {
|
||||
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
|
||||
verify_ty_bound(
|
||||
|
@ -201,13 +203,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCopyConst {
|
|||
return;
|
||||
}
|
||||
|
||||
// make sure it is a const item.
|
||||
// Make sure it is a const item.
|
||||
match cx.tables.qpath_def(qpath, expr.hir_id) {
|
||||
Def::Const(_) | Def::AssociatedConst(_) => {},
|
||||
_ => return,
|
||||
};
|
||||
|
||||
// climb up to resolve any field access and explicit referencing.
|
||||
// Climb up to resolve any field access and explicit referencing.
|
||||
let mut cur_expr = expr;
|
||||
let mut dereferenced_expr = expr;
|
||||
let mut needs_check_adjustment = true;
|
||||
|
@ -219,7 +221,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCopyConst {
|
|||
if let Some(Node::Expr(parent_expr)) = cx.tcx.hir().find_by_hir_id(parent_id) {
|
||||
match &parent_expr.node {
|
||||
ExprKind::AddrOf(..) => {
|
||||
// `&e` => `e` must be referenced
|
||||
// `&e` => `e` must be referenced.
|
||||
needs_check_adjustment = false;
|
||||
},
|
||||
ExprKind::Field(..) => {
|
||||
|
@ -260,7 +262,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCopyConst {
|
|||
adjustments[i - 1].target
|
||||
}
|
||||
} else {
|
||||
// No borrow adjustments = the entire const is moved.
|
||||
// No borrow adjustments means the entire const is moved.
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
use crate::utils::sugg::Sugg;
|
||||
use if_chain::if_chain;
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
use syntax::ptr::P;
|
||||
|
||||
use crate::utils::paths::*;
|
||||
use crate::utils::{match_def_path, match_type, span_lint_and_then, SpanlessEq};
|
||||
use rustc_errors::Applicability;
|
||||
use crate::utils::paths::*;
|
||||
use crate::utils::sugg::Sugg;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for expressions that could be replaced by the question mark operator
|
||||
/// **What it does:** Checks for expressions that could be replaced by the question mark operator.
|
||||
///
|
||||
/// **Why is this bad?** Question mark usage is more idiomatic
|
||||
/// **Why is this bad?** Question mark usage is more idiomatic.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
|
@ -48,11 +48,11 @@ impl LintPass for Pass {
|
|||
}
|
||||
|
||||
impl Pass {
|
||||
/// Check if the given expression on the given context matches the following structure:
|
||||
/// Checks if the given expression on the given context matches the following structure:
|
||||
///
|
||||
/// ```ignore
|
||||
/// if option.is_none() {
|
||||
/// return None;
|
||||
/// return `None`;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
use crate::utils::sugg::Sugg;
|
||||
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};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
|
@ -9,6 +6,10 @@ use rustc_errors::Applicability;
|
|||
use syntax::ast::RangeLimits;
|
||||
use syntax::source_map::Spanned;
|
||||
|
||||
use crate::utils::sugg::Sugg;
|
||||
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};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for calling `.step_by(0)` on iterators,
|
||||
/// which never terminates.
|
||||
|
@ -48,7 +49,7 @@ declare_clippy_lint! {
|
|||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for exclusive ranges where 1 is added to the
|
||||
/// upper bound, e.g. `x..(y+1)`.
|
||||
/// upper bound, e.g., `x..(y+1)`.
|
||||
///
|
||||
/// **Why is this bad?** The code is more readable with an inclusive range
|
||||
/// like `x..=y`.
|
||||
|
@ -56,7 +57,7 @@ declare_clippy_lint! {
|
|||
/// **Known problems:** Will add unnecessary pair of parentheses when the
|
||||
/// expression is not wrapped in a pair but starts with a opening parenthesis
|
||||
/// and ends with a closing one.
|
||||
/// I.e: `let _ = (f()+1)..(f()+1)` results in `let _ = ((f()+1)..=f())`.
|
||||
/// I.e., `let _ = (f()+1)..(f()+1)` results in `let _ = ((f()+1)..=f())`.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
|
@ -69,7 +70,7 @@ declare_clippy_lint! {
|
|||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for inclusive ranges where 1 is subtracted from
|
||||
/// the upper bound, e.g. `x..=(y-1)`.
|
||||
/// the upper bound, e.g., `x..=(y-1)`.
|
||||
///
|
||||
/// **Why is this bad?** The code is more readable with an exclusive range
|
||||
/// like `x..y`.
|
||||
|
@ -123,16 +124,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
let iter = &args[0].node;
|
||||
let zip_arg = &args[1];
|
||||
if_chain! {
|
||||
// .iter() call
|
||||
// `.iter()` call
|
||||
if let ExprKind::MethodCall(ref iter_path, _, ref iter_args ) = *iter;
|
||||
if iter_path.ident.name == "iter";
|
||||
// range expression in .zip() call: 0..x.len()
|
||||
// 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
|
||||
// `.len()` call
|
||||
if let ExprKind::MethodCall(ref len_path, _, ref len_args) = end.node;
|
||||
if len_path.ident.name == "len" && len_args.len() == 1;
|
||||
// .iter() and .len() called on same Path
|
||||
// `.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;
|
||||
if SpanlessEq::new(cx).eq_path_segments(&iter_path.segments, &len_path.segments);
|
||||
|
@ -147,7 +148,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
}
|
||||
}
|
||||
|
||||
// exclusive range plus one: x..(y+1)
|
||||
// exclusive range plus one: `x..(y+1)`
|
||||
if_chain! {
|
||||
if let Some(higher::Range {
|
||||
start,
|
||||
|
@ -186,7 +187,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
}
|
||||
}
|
||||
|
||||
// inclusive range minus one: x..=(y-1)
|
||||
// inclusive range minus one: `x..=(y-1)`
|
||||
if_chain! {
|
||||
if let Some(higher::Range { start, end: Some(end), limits: RangeLimits::Closed }) = higher::range(cx, expr);
|
||||
if let Some(y) = y_minus_one(end);
|
||||
|
@ -213,7 +214,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
}
|
||||
|
||||
fn has_step_by(cx: &LateContext<'_, '_>, expr: &Expr) -> bool {
|
||||
// No need for walk_ptrs_ty here because step_by moves self, so it
|
||||
// No need for `walk_ptrs_ty` here because `step_by` moves `self`, so it
|
||||
// can't be called on a borrowed range.
|
||||
let ty = cx.tables.expr_ty_adjusted(expr);
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::utils::{in_macro, match_path_ast, snippet_opt, span_lint_and_then, span_note_and_lint};
|
||||
use if_chain::if_chain;
|
||||
use rustc::lint::{in_external_macro, EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
@ -8,6 +7,8 @@ use syntax::source_map::Span;
|
|||
use syntax::visit::FnKind;
|
||||
use syntax_pos::BytePos;
|
||||
|
||||
use crate::utils::{in_macro, match_path_ast, snippet_opt, span_lint_and_then, span_note_and_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for return statements at the end of a block.
|
||||
///
|
||||
|
@ -69,7 +70,7 @@ declare_clippy_lint! {
|
|||
/// statement look like a function call.
|
||||
///
|
||||
/// **Known problems:** The lint currently misses unit return types in types,
|
||||
/// e.g. the `F` in `fn generic_unit<F: Fn() -> ()>(f: F) { .. }`.
|
||||
/// e.g., the `F` in `fn generic_unit<F: Fn() -> ()>(f: F) { .. }`.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
|
|
|
@ -24,7 +24,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub SHADOW_SAME,
|
||||
restriction,
|
||||
"rebinding a name to itself, e.g. `let mut x = &mut x`"
|
||||
"rebinding a name to itself, e.g., `let mut x = &mut x`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -49,7 +49,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub SHADOW_REUSE,
|
||||
restriction,
|
||||
"rebinding a name to an expression that re-uses the original value, e.g. `let x = x + 1`"
|
||||
"rebinding a name to an expression that re-uses the original value, e.g., `let x = x + 1`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
|
|
@ -194,13 +194,13 @@ impl Pass {
|
|||
struct VectorInitializationVisitor<'a, 'tcx: 'a> {
|
||||
cx: &'a LateContext<'a, 'tcx>,
|
||||
|
||||
/// Contains the information
|
||||
/// Contains the information.
|
||||
vec_alloc: VecAllocation<'tcx>,
|
||||
|
||||
/// Contains, if found, the slow initialization expression
|
||||
/// Contains, the slow initialization expression, if one was found.
|
||||
slow_expression: Option<InitializationType<'tcx>>,
|
||||
|
||||
/// true if the initialization of the vector has been found on the visited block
|
||||
/// `true` if the initialization of the vector has been found on the visited block.
|
||||
initialization_found: bool,
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
use crate::utils::SpanlessEq;
|
||||
use crate::utils::{get_parent_expr, is_allowed, match_type, paths, span_lint, span_lint_and_sugg, walk_ptrs_ty};
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
use syntax::source_map::Spanned;
|
||||
|
||||
use crate::utils::SpanlessEq;
|
||||
use crate::utils::{get_parent_expr, is_allowed, match_type, paths, span_lint, span_lint_and_sugg, walk_ptrs_ty};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for string appends of the form `x = x + y` (without
|
||||
/// `let`!).
|
||||
|
@ -35,7 +36,7 @@ declare_clippy_lint! {
|
|||
/// `Add` implementation is asymmetric (the other operand need not be `String`,
|
||||
/// but `x` does), while addition as mathematically defined is symmetric, also
|
||||
/// the `String::push_str(_)` function is a perfectly good replacement.
|
||||
/// Therefore some dislike it and wish not to have it in their code.
|
||||
/// Therefore, some dislike it and wish not to have it in their code.
|
||||
///
|
||||
/// That said, other people think that string addition, having a long tradition
|
||||
/// in other languages is actually fine, which is why we decided to make this
|
||||
|
@ -58,7 +59,7 @@ declare_clippy_lint! {
|
|||
/// **What it does:** Checks for the `as_bytes` method called on string literals
|
||||
/// that contain only ASCII characters.
|
||||
///
|
||||
/// **Why is this bad?** Byte string literals (e.g. `b"foo"`) can be used
|
||||
/// **Why is this bad?** Byte string literals (e.g., `b"foo"`) can be used
|
||||
/// instead. They are shorter but less discoverable than `as_bytes()`.
|
||||
///
|
||||
/// **Known Problems:** None.
|
||||
|
|
|
@ -485,7 +485,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get the snippet of `Bar` in `…::transmute<Foo, &Bar>`. If that snippet is
|
||||
/// Gets the snippet of `Bar` in `…::transmute<Foo, &Bar>`. If that snippet is
|
||||
/// not available , use
|
||||
/// the type's `ToString` implementation. In weird cases it could lead to types
|
||||
/// with invalid `'_`
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
#![allow(clippy::default_hash_types)]
|
||||
|
||||
use crate::consts::{constant, Constant};
|
||||
use crate::utils::paths;
|
||||
use crate::utils::{
|
||||
clip, comparisons, differing_macro_contexts, higher, in_constant, in_macro, int_bits, last_path_segment,
|
||||
match_def_path, match_path, multispan_sugg, same_tys, sext, snippet, snippet_opt, snippet_with_applicability,
|
||||
span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, unsext, AbsolutePathBuffer,
|
||||
};
|
||||
use std::borrow::Cow;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir;
|
||||
use rustc::hir::intravisit::{walk_body, walk_expr, walk_ty, FnKind, NestedVisitorMap, Visitor};
|
||||
|
@ -18,13 +15,18 @@ use rustc::{declare_tool_lint, lint_array};
|
|||
use rustc_errors::Applicability;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use rustc_typeck::hir_ty_to_ty;
|
||||
use std::borrow::Cow;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::BTreeMap;
|
||||
use syntax::ast::{FloatTy, IntTy, UintTy};
|
||||
use syntax::errors::DiagnosticBuilder;
|
||||
use syntax::source_map::Span;
|
||||
|
||||
use crate::consts::{constant, Constant};
|
||||
use crate::utils::paths;
|
||||
use crate::utils::{
|
||||
clip, comparisons, differing_macro_contexts, higher, in_constant, in_macro, int_bits, last_path_segment,
|
||||
match_def_path, match_path, multispan_sugg, same_tys, sext, snippet, snippet_opt, snippet_with_applicability,
|
||||
span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, unsext, AbsolutePathBuffer,
|
||||
};
|
||||
|
||||
/// Handles all the linting of funky types
|
||||
pub struct TypePass;
|
||||
|
||||
|
@ -174,7 +176,7 @@ impl LintPass for TypePass {
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypePass {
|
||||
fn check_fn(&mut self, cx: &LateContext<'_, '_>, _: FnKind<'_>, decl: &FnDecl, _: &Body, _: Span, id: HirId) {
|
||||
// skip trait implementations, see #605
|
||||
// Skip trait implementations; see issue #605.
|
||||
if let Some(hir::Node::Item(item)) = cx.tcx.hir().find_by_hir_id(cx.tcx.hir().get_parent_item(id)) {
|
||||
if let ItemKind::Impl(_, _, _, _, Some(..), _, _) = item.node {
|
||||
return;
|
||||
|
@ -213,7 +215,7 @@ fn check_fn_decl(cx: &LateContext<'_, '_>, decl: &FnDecl) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Check if `qpath` has last segment with type parameter matching `path`
|
||||
/// Checks if `qpath` has last segment with type parameter matching `path`
|
||||
fn match_type_parameter(cx: &LateContext<'_, '_>, qpath: &QPath, path: &[&str]) -> bool {
|
||||
let last = last_path_segment(qpath);
|
||||
if_chain! {
|
||||
|
@ -389,7 +391,7 @@ fn check_ty_rptr(cx: &LateContext<'_, '_>, hir_ty: &hir::Ty, is_local: bool, lt:
|
|||
});
|
||||
then {
|
||||
if is_any_trait(inner) {
|
||||
// Ignore `Box<Any>` types, see #1884 for details.
|
||||
// Ignore `Box<Any>` types; see issue #1884 for details.
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -698,7 +700,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub CAST_PRECISION_LOSS,
|
||||
pedantic,
|
||||
"casts that cause loss of precision, e.g. `x as f32` where `x: u64`"
|
||||
"casts that cause loss of precision, e.g., `x as f32` where `x: u64`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -719,7 +721,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub CAST_SIGN_LOSS,
|
||||
pedantic,
|
||||
"casts from signed types to unsigned types, e.g. `x as u32` where `x: i32`"
|
||||
"casts from signed types to unsigned types, e.g., `x as u32` where `x: i32`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -741,13 +743,13 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub CAST_POSSIBLE_TRUNCATION,
|
||||
pedantic,
|
||||
"casts that may cause truncation of the value, e.g. `x as u8` where `x: u32`, or `x as i32` where `x: f32`"
|
||||
"casts that may cause truncation of the value, e.g., `x as u8` where `x: u32`, or `x as i32` where `x: f32`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for casts from an unsigned type to a signed type of
|
||||
/// the same size. Performing such a cast is a 'no-op' for the compiler,
|
||||
/// i.e. nothing is changed at the bit level, and the binary representation of
|
||||
/// i.e., nothing is changed at the bit level, and the binary representation of
|
||||
/// the value is reinterpreted. This can cause wrapping if the value is too big
|
||||
/// for the target signed type. However, the cast works as defined, so this lint
|
||||
/// is `Allow` by default.
|
||||
|
@ -764,7 +766,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub CAST_POSSIBLE_WRAP,
|
||||
pedantic,
|
||||
"casts that may cause wrapping around the value, e.g. `x as i32` where `x: u32` and `x > i32::MAX`"
|
||||
"casts that may cause wrapping around the value, e.g., `x as i32` where `x: u32` and `x > i32::MAX`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -796,7 +798,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub CAST_LOSSLESS,
|
||||
complexity,
|
||||
"casts using `as` that are known to be lossless, e.g. `x as u64` where `x: u8`"
|
||||
"casts using `as` that are known to be lossless, e.g., `x as u64` where `x: u8`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -812,7 +814,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub UNNECESSARY_CAST,
|
||||
complexity,
|
||||
"cast to the same type, e.g. `x as i32` where `x: i32`"
|
||||
"cast to the same type, e.g., `x as i32` where `x: i32`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -1528,14 +1530,14 @@ declare_clippy_lint! {
|
|||
/// `max < x` are probably mistakes.
|
||||
///
|
||||
/// **Known problems:** For `usize` the size of the current compile target will
|
||||
/// be assumed (e.g. 64 bits on 64 bit systems). This means code that uses such
|
||||
/// be assumed (e.g., 64 bits on 64 bit systems). This means code that uses such
|
||||
/// a comparison to detect target pointer width will trigger this lint. One can
|
||||
/// use `mem::sizeof` and compare its value or conditional compilation
|
||||
/// attributes
|
||||
/// like `#[cfg(target_pointer_width = "64")] ..` instead.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// ```rust
|
||||
/// vec.len() <= 0
|
||||
/// 100 > std::i32::MAX
|
||||
/// ```
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::utils::span_lint_and_sugg;
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir::def::{CtorKind, Def};
|
||||
use rustc::hir::intravisit::{walk_item, walk_path, walk_ty, NestedVisitorMap, Visitor};
|
||||
|
@ -9,6 +8,8 @@ use rustc::{declare_tool_lint, lint_array};
|
|||
use rustc_errors::Applicability;
|
||||
use syntax_pos::symbol::keywords::SelfUpper;
|
||||
|
||||
use crate::utils::span_lint_and_sugg;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for unnecessary repetition of structure name when a
|
||||
/// replacement with `Self` is applicable.
|
||||
|
@ -60,9 +61,9 @@ impl LintPass for UseSelf {
|
|||
const SEGMENTS_MSG: &str = "segments should be composed of at least 1 element";
|
||||
|
||||
fn span_use_self_lint(cx: &LateContext<'_, '_>, path: &Path) {
|
||||
// path segments only include actual path, no methods or fields
|
||||
// Path segments only include actual path, no methods or fields.
|
||||
let last_path_span = path.segments.last().expect(SEGMENTS_MSG).ident.span;
|
||||
// only take path up to the end of last_path_span
|
||||
// Only take path up to the end of last_path_span.
|
||||
let span = path.span.with_hi(last_path_span.hi());
|
||||
|
||||
span_lint_and_sugg(
|
||||
|
@ -149,7 +150,7 @@ fn check_trait_method_impl_decl<'a, 'tcx: 'a>(
|
|||
|
||||
// `impl_decl_ty` (of type `hir::Ty`) represents the type declared in the signature.
|
||||
// `impl_ty` (of type `ty:TyS`) is the concrete type that the compiler has determined for
|
||||
// that declaration. We use `impl_decl_ty` to see if the type was declared as `Self`
|
||||
// that declaration. We use `impl_decl_ty` to see if the type was declared as `Self`
|
||||
// and use `impl_ty` to check its concrete type.
|
||||
for (impl_decl_ty, (impl_ty, trait_ty)) in impl_decl.inputs.iter().chain(output_ty).zip(
|
||||
impl_method_sig
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/// Return the index of the character after the first camel-case component of
|
||||
/// Returns the index of the character after the first camel-case component of
|
||||
/// `s`.
|
||||
pub fn until(s: &str) -> usize {
|
||||
let mut iter = s.char_indices();
|
||||
|
@ -32,7 +32,7 @@ pub fn until(s: &str) -> usize {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return index of the last camel-case component of `s`.
|
||||
/// Returns index of the last camel-case component of `s`.
|
||||
pub fn from(s: &str) -> usize {
|
||||
let mut iter = s.char_indices().rev();
|
||||
if let Some((_, first)) = iter.next() {
|
||||
|
|
|
@ -10,7 +10,7 @@ use std::{env, fmt, fs, io, path};
|
|||
use syntax::{ast, source_map};
|
||||
use toml;
|
||||
|
||||
/// Get the configuration file from arguments.
|
||||
/// Gets the configuration file from arguments.
|
||||
pub fn file_from_args(
|
||||
args: &[source_map::Spanned<ast::NestedMetaItemKind>],
|
||||
) -> Result<Option<path::PathBuf>, (&'static str, source_map::Span)> {
|
||||
|
|
|
@ -9,7 +9,7 @@ use rustc::lint::LateContext;
|
|||
use rustc::{hir, ty};
|
||||
use syntax::ast;
|
||||
|
||||
/// Convert a hir binary operator to the corresponding `ast` type.
|
||||
/// Converts a hir binary operator to the corresponding `ast` type.
|
||||
pub fn binop(op: hir::BinOpKind) -> ast::BinOpKind {
|
||||
match op {
|
||||
hir::BinOpKind::Eq => ast::BinOpKind::Eq,
|
||||
|
@ -46,7 +46,7 @@ pub struct Range<'a> {
|
|||
|
||||
/// Higher a `hir` range to something similar to `ast::ExprKind::Range`.
|
||||
pub fn range<'a, 'b, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'b hir::Expr) -> Option<Range<'b>> {
|
||||
/// Find the field named `name` in the field. Always return `Some` for
|
||||
/// Finds the field named `name` in the field. Always return `Some` for
|
||||
/// convenience.
|
||||
fn get_field<'a>(name: &str, fields: &'a [hir::Field]) -> Option<&'a hir::Expr> {
|
||||
let expr = &fields.iter().find(|field| field.ident.name == name)?.expr;
|
||||
|
|
|
@ -40,7 +40,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Check whether two statements are the same.
|
||||
/// Checks whether two statements are the same.
|
||||
pub fn eq_stmt(&mut self, left: &Stmt, right: &Stmt) -> bool {
|
||||
match (&left.node, &right.node) {
|
||||
(&StmtKind::Local(ref l), &StmtKind::Local(ref r)) => {
|
||||
|
@ -55,7 +55,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Check whether two blocks are the same.
|
||||
/// Checks whether two blocks are the same.
|
||||
pub fn eq_block(&mut self, left: &Block, right: &Block) -> bool {
|
||||
over(&left.stmts, &right.stmts, |l, r| self.eq_stmt(l, r))
|
||||
&& both(&left.expr, &right.expr, |l, r| self.eq_expr(l, r))
|
||||
|
@ -186,7 +186,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
|
|||
left.name == right.name
|
||||
}
|
||||
|
||||
/// Check whether two patterns are the same.
|
||||
/// Checks whether two patterns are the same.
|
||||
pub fn eq_pat(&mut self, left: &Pat, right: &Pat) -> bool {
|
||||
match (&left.node, &right.node) {
|
||||
(&PatKind::Box(ref l), &PatKind::Box(ref r)) => self.eq_pat(l, r),
|
||||
|
@ -328,7 +328,7 @@ fn swap_binop<'a>(binop: BinOpKind, lhs: &'a Expr, rhs: &'a Expr) -> Option<(Bin
|
|||
}
|
||||
}
|
||||
|
||||
/// Check if the two `Option`s are both `None` or some equal values as per
|
||||
/// Checks if the two `Option`s are both `None` or some equal values as per
|
||||
/// `eq_fn`.
|
||||
fn both<X, F>(l: &Option<X>, r: &Option<X>, mut eq_fn: F) -> bool
|
||||
where
|
||||
|
@ -338,7 +338,7 @@ where
|
|||
.map_or_else(|| r.is_none(), |x| r.as_ref().map_or(false, |y| eq_fn(x, y)))
|
||||
}
|
||||
|
||||
/// Check if two slices are equal as per `eq_fn`.
|
||||
/// Checks if two slices are equal as per `eq_fn`.
|
||||
fn over<X, F>(left: &[X], right: &[X], mut eq_fn: F) -> bool
|
||||
where
|
||||
F: FnMut(&X, &X) -> bool,
|
||||
|
|
|
@ -1,30 +1,3 @@
|
|||
use crate::reexport::*;
|
||||
use if_chain::if_chain;
|
||||
use matches::matches;
|
||||
use rustc::hir;
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||
use rustc::hir::intravisit::{NestedVisitorMap, Visitor};
|
||||
use rustc::hir::Node;
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, Level, Lint, LintContext};
|
||||
use rustc::traits;
|
||||
use rustc::ty::{
|
||||
self,
|
||||
layout::{self, IntegerExt},
|
||||
subst::Kind,
|
||||
Binder, Ty, TyCtxt,
|
||||
};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::Applicability;
|
||||
use std::borrow::Cow;
|
||||
use std::mem;
|
||||
use syntax::ast::{self, LitKind};
|
||||
use syntax::attr;
|
||||
use syntax::source_map::{Span, DUMMY_SP};
|
||||
use syntax::symbol;
|
||||
use syntax::symbol::{keywords, Symbol};
|
||||
|
||||
pub mod attrs;
|
||||
pub mod author;
|
||||
pub mod camel_case;
|
||||
|
@ -44,9 +17,37 @@ pub use self::attrs::*;
|
|||
pub use self::diagnostics::*;
|
||||
pub use self::hir_utils::{SpanlessEq, SpanlessHash};
|
||||
|
||||
/// Returns true if the two spans come from differing expansions (i.e. one is
|
||||
/// from a macro and one
|
||||
/// isn't).
|
||||
use std::borrow::Cow;
|
||||
use std::mem;
|
||||
|
||||
use if_chain::if_chain;
|
||||
use matches::matches;
|
||||
use rustc::hir;
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||
use rustc::hir::intravisit::{NestedVisitorMap, Visitor};
|
||||
use rustc::hir::Node;
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, Level, Lint, LintContext};
|
||||
use rustc::traits;
|
||||
use rustc::ty::{
|
||||
self,
|
||||
layout::{self, IntegerExt},
|
||||
subst::Kind,
|
||||
Binder, Ty, TyCtxt,
|
||||
};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::Applicability;
|
||||
use syntax::ast::{self, LitKind};
|
||||
use syntax::attr;
|
||||
use syntax::source_map::{Span, DUMMY_SP};
|
||||
use syntax::symbol;
|
||||
use syntax::symbol::{keywords, Symbol};
|
||||
|
||||
use crate::reexport::*;
|
||||
|
||||
/// Returns `true` if the two spans come from differing expansions (i.e., one is
|
||||
/// from a macro and one isn't).
|
||||
pub fn differing_macro_contexts(lhs: Span, rhs: Span) -> bool {
|
||||
rhs.ctxt() != lhs.ctxt()
|
||||
}
|
||||
|
@ -88,7 +89,7 @@ pub fn in_constant(cx: &LateContext<'_, '_>, id: HirId) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns true if this `expn_info` was expanded by any macro.
|
||||
/// Returns `true` if this `expn_info` was expanded by any macro.
|
||||
pub fn in_macro(span: Span) -> bool {
|
||||
span.ctxt().outer().expn_info().is_some()
|
||||
}
|
||||
|
@ -112,7 +113,7 @@ impl ty::item_path::ItemPathBuffer for AbsolutePathBuffer {
|
|||
}
|
||||
}
|
||||
|
||||
/// Check if a `DefId`'s path matches the given absolute type path usage.
|
||||
/// Checks if a `DefId`'s path matches the given absolute type path usage.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust,ignore
|
||||
|
@ -128,7 +129,7 @@ pub fn match_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, path: &[&str]) ->
|
|||
apb.names.len() == path.len() && apb.names.into_iter().zip(path.iter()).all(|(a, &b)| *a == *b)
|
||||
}
|
||||
|
||||
/// Get the absolute path of `def_id` as a vector of `&str`.
|
||||
/// Gets the absolute path of `def_id` as a vector of `&str`.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust,ignore
|
||||
|
@ -146,7 +147,7 @@ pub fn get_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Vec<&'static str>
|
|||
.collect()
|
||||
}
|
||||
|
||||
/// Check if type is struct, enum or union type with given def path.
|
||||
/// Checks if type is struct, enum or union type with given def path.
|
||||
pub fn match_type(cx: &LateContext<'_, '_>, ty: Ty<'_>, path: &[&str]) -> bool {
|
||||
match ty.sty {
|
||||
ty::Adt(adt, _) => match_def_path(cx.tcx, adt.did, path),
|
||||
|
@ -154,7 +155,7 @@ pub fn match_type(cx: &LateContext<'_, '_>, ty: Ty<'_>, path: &[&str]) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
/// Check if the method call given in `expr` belongs to given trait.
|
||||
/// Checks if the method call given in `expr` belongs to given trait.
|
||||
pub fn match_trait_method(cx: &LateContext<'_, '_>, expr: &Expr, path: &[&str]) -> bool {
|
||||
let method_call = cx.tables.type_dependent_defs()[expr.hir_id];
|
||||
let trt_id = cx.tcx.trait_of_item(method_call.def_id());
|
||||
|
@ -165,7 +166,7 @@ pub fn match_trait_method(cx: &LateContext<'_, '_>, expr: &Expr, path: &[&str])
|
|||
}
|
||||
}
|
||||
|
||||
/// Check if an expression references a variable of the given name.
|
||||
/// Checks if an expression references a variable of the given name.
|
||||
pub fn match_var(expr: &Expr, var: Name) -> bool {
|
||||
if let ExprKind::Path(QPath::Resolved(None, ref path)) = expr.node {
|
||||
if path.segments.len() == 1 && path.segments[0].ident.name == var {
|
||||
|
@ -190,7 +191,7 @@ pub fn single_segment_path(path: &QPath) -> Option<&PathSegment> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Match a `QPath` against a slice of segment string literals.
|
||||
/// Matches a `QPath` against a slice of segment string literals.
|
||||
///
|
||||
/// There is also `match_path` if you are dealing with a `rustc::hir::Path` instead of a
|
||||
/// `rustc::hir::QPath`.
|
||||
|
@ -213,7 +214,7 @@ pub fn match_qpath(path: &QPath, segments: &[&str]) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
/// Match a `Path` against a slice of segment string literals.
|
||||
/// Matches a `Path` against a slice of segment string literals.
|
||||
///
|
||||
/// There is also `match_qpath` if you are dealing with a `rustc::hir::QPath` instead of a
|
||||
/// `rustc::hir::Path`.
|
||||
|
@ -237,7 +238,7 @@ pub fn match_path(path: &Path, segments: &[&str]) -> bool {
|
|||
.all(|(a, b)| a.ident.name == *b)
|
||||
}
|
||||
|
||||
/// Match a `Path` against a slice of segment string literals, e.g.
|
||||
/// Matches a `Path` against a slice of segment string literals, e.g.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust,ignore
|
||||
|
@ -251,7 +252,7 @@ pub fn match_path_ast(path: &ast::Path, segments: &[&str]) -> bool {
|
|||
.all(|(a, b)| a.ident.name == *b)
|
||||
}
|
||||
|
||||
/// Get the definition associated to a path.
|
||||
/// Gets the definition associated to a path.
|
||||
pub fn path_to_def(cx: &LateContext<'_, '_>, path: &[&str]) -> Option<def::Def> {
|
||||
let crates = cx.tcx.crates();
|
||||
let krate = crates.iter().find(|&&krate| cx.tcx.crate_name(krate) == path[0]);
|
||||
|
@ -298,7 +299,7 @@ pub fn get_trait_def_id(cx: &LateContext<'_, '_>, path: &[&str]) -> Option<DefId
|
|||
}
|
||||
}
|
||||
|
||||
/// Check whether a type implements a trait.
|
||||
/// Checks whether a type implements a trait.
|
||||
/// See also `get_trait_def_id`.
|
||||
pub fn implements_trait<'a, 'tcx>(
|
||||
cx: &LateContext<'a, 'tcx>,
|
||||
|
@ -320,7 +321,7 @@ pub fn implements_trait<'a, 'tcx>(
|
|||
.enter(|infcx| infcx.predicate_must_hold_modulo_regions(&obligation))
|
||||
}
|
||||
|
||||
/// Get the `hir::TraitRef` of the trait the given method is implemented for
|
||||
/// Gets the `hir::TraitRef` of the trait the given method is implemented for.
|
||||
///
|
||||
/// Use this if you want to find the `TraitRef` of the `Add` trait in this example:
|
||||
///
|
||||
|
@ -347,7 +348,7 @@ pub fn trait_ref_of_method(cx: &LateContext<'_, '_>, hir_id: HirId) -> Option<Tr
|
|||
None
|
||||
}
|
||||
|
||||
/// Check whether this type implements Drop.
|
||||
/// Checks whether this type implements `Drop`.
|
||||
pub fn has_drop<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
match ty.ty_adt_def() {
|
||||
Some(def) => def.has_dtor(cx.tcx),
|
||||
|
@ -355,12 +356,12 @@ pub fn has_drop<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
/// Resolve the definition of a node from its `HirId`.
|
||||
/// Resolves the definition of a node from its `HirId`.
|
||||
pub fn resolve_node(cx: &LateContext<'_, '_>, qpath: &QPath, id: HirId) -> def::Def {
|
||||
cx.tables.qpath_def(qpath, id)
|
||||
}
|
||||
|
||||
/// Return the method names and argument list of nested method call expressions that make up
|
||||
/// Returns the method names and argument list of nested method call expressions that make up
|
||||
/// `expr`.
|
||||
pub fn method_calls<'a>(expr: &'a Expr, max_depth: usize) -> (Vec<Symbol>, Vec<&'a [Expr]>) {
|
||||
let mut method_names = Vec::with_capacity(max_depth);
|
||||
|
@ -383,7 +384,7 @@ pub fn method_calls<'a>(expr: &'a Expr, max_depth: usize) -> (Vec<Symbol>, Vec<&
|
|||
(method_names, arg_lists)
|
||||
}
|
||||
|
||||
/// Match an `Expr` against a chain of methods, and return the matched `Expr`s.
|
||||
/// Matches an `Expr` against a chain of methods, and return the matched `Expr`s.
|
||||
///
|
||||
/// For example, if `expr` represents the `.baz()` in `foo.bar().baz()`,
|
||||
/// `matched_method_chain(expr, &["bar", "baz"])` will return a `Vec`
|
||||
|
@ -408,11 +409,12 @@ pub fn method_chain_args<'a>(expr: &'a Expr, methods: &[&str]) -> Option<Vec<&'a
|
|||
return None;
|
||||
}
|
||||
}
|
||||
matched.reverse(); // reverse `matched`, so that it is in the same order as `methods`
|
||||
// Reverse `matched` so that it is in the same order as `methods`.
|
||||
matched.reverse();
|
||||
Some(matched)
|
||||
}
|
||||
|
||||
/// Returns true if the provided `def_id` is an entrypoint to a program
|
||||
/// Returns `true` if the provided `def_id` is an entrypoint to a program.
|
||||
pub fn is_entrypoint_fn(cx: &LateContext<'_, '_>, def_id: DefId) -> bool {
|
||||
if let Some((entry_fn_def_id, _)) = cx.tcx.entry_fn(LOCAL_CRATE) {
|
||||
return def_id == entry_fn_def_id;
|
||||
|
@ -420,7 +422,7 @@ pub fn is_entrypoint_fn(cx: &LateContext<'_, '_>, def_id: DefId) -> bool {
|
|||
false
|
||||
}
|
||||
|
||||
/// Get the name of the item the expression is in, if available.
|
||||
/// Gets the name of the item the expression is in, if available.
|
||||
pub fn get_item_name(cx: &LateContext<'_, '_>, expr: &Expr) -> Option<Name> {
|
||||
let parent_id = cx.tcx.hir().get_parent_item(expr.hir_id);
|
||||
match cx.tcx.hir().find_by_hir_id(parent_id) {
|
||||
|
@ -432,7 +434,7 @@ pub fn get_item_name(cx: &LateContext<'_, '_>, expr: &Expr) -> Option<Name> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get the name of a `Pat`, if any
|
||||
/// Gets the name of a `Pat`, if any
|
||||
pub fn get_pat_name(pat: &Pat) -> Option<Name> {
|
||||
match pat.node {
|
||||
PatKind::Binding(.., ref spname, _) => Some(spname.name),
|
||||
|
@ -458,14 +460,14 @@ impl<'tcx> Visitor<'tcx> for ContainsName {
|
|||
}
|
||||
}
|
||||
|
||||
/// check if an `Expr` contains a certain name
|
||||
/// Checks if an `Expr` contains a certain name.
|
||||
pub fn contains_name(name: Name, expr: &Expr) -> bool {
|
||||
let mut cn = ContainsName { name, result: false };
|
||||
cn.visit_expr(expr);
|
||||
cn.result
|
||||
}
|
||||
|
||||
/// Convert a span to a code snippet if available, otherwise use default.
|
||||
/// Converts a span to a code snippet if available, otherwise use default.
|
||||
///
|
||||
/// This is useful if you want to provide suggestions for your lint or more generally, if you want
|
||||
/// to convert a given `Span` to a `str`.
|
||||
|
@ -510,12 +512,12 @@ pub fn snippet_with_macro_callsite<'a, 'b, T: LintContext<'b>>(cx: &T, span: Spa
|
|||
snippet(cx, span.source_callsite(), default)
|
||||
}
|
||||
|
||||
/// Convert a span to a code snippet. Returns `None` if not available.
|
||||
/// Converts a span to a code snippet. Returns `None` if not available.
|
||||
pub fn snippet_opt<'a, T: LintContext<'a>>(cx: &T, span: Span) -> Option<String> {
|
||||
cx.sess().source_map().span_to_snippet(span).ok()
|
||||
}
|
||||
|
||||
/// Convert a span (from a block) to a code snippet if available, otherwise use
|
||||
/// Converts a span (from a block) to a code snippet if available, otherwise use
|
||||
/// default.
|
||||
/// This trims the code of indentation, except for the first line. Use it for
|
||||
/// blocks or block-like
|
||||
|
@ -612,7 +614,7 @@ fn trim_multiline_inner(s: Cow<'_, str>, ignore_first: bool, ch: char) -> Cow<'_
|
|||
}
|
||||
}
|
||||
|
||||
/// Get a parent expressions if any – this is useful to constrain a lint.
|
||||
/// Gets a parent expressions if any – this is useful to constrain a lint.
|
||||
pub fn get_parent_expr<'c>(cx: &'c LateContext<'_, '_>, e: &Expr) -> Option<&'c Expr> {
|
||||
let map = &cx.tcx.hir();
|
||||
let hir_id = e.hir_id;
|
||||
|
@ -656,7 +658,7 @@ pub fn get_enclosing_block<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, node: HirId
|
|||
}
|
||||
}
|
||||
|
||||
/// Return the base type for HIR references and pointers.
|
||||
/// Returns the base type for HIR references and pointers.
|
||||
pub fn walk_ptrs_hir_ty(ty: &hir::Ty) -> &hir::Ty {
|
||||
match ty.node {
|
||||
TyKind::Ptr(ref mut_ty) | TyKind::Rptr(_, ref mut_ty) => walk_ptrs_hir_ty(&mut_ty.ty),
|
||||
|
@ -664,7 +666,7 @@ pub fn walk_ptrs_hir_ty(ty: &hir::Ty) -> &hir::Ty {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return the base type for references and raw pointers.
|
||||
/// Returns the base type for references and raw pointers.
|
||||
pub fn walk_ptrs_ty(ty: Ty<'_>) -> Ty<'_> {
|
||||
match ty.sty {
|
||||
ty::Ref(_, ty, _) => walk_ptrs_ty(ty),
|
||||
|
@ -672,7 +674,7 @@ pub fn walk_ptrs_ty(ty: Ty<'_>) -> Ty<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return the base type for references and raw pointers, and count reference
|
||||
/// Returns the base type for references and raw pointers, and count reference
|
||||
/// depth.
|
||||
pub fn walk_ptrs_ty_depth(ty: Ty<'_>) -> (Ty<'_>, usize) {
|
||||
fn inner(ty: Ty<'_>, depth: usize) -> (Ty<'_>, usize) {
|
||||
|
@ -684,7 +686,7 @@ pub fn walk_ptrs_ty_depth(ty: Ty<'_>) -> (Ty<'_>, usize) {
|
|||
inner(ty, 0)
|
||||
}
|
||||
|
||||
/// Check whether the given expression is a constant literal of the given value.
|
||||
/// Checks whether the given expression is a constant literal of the given value.
|
||||
pub fn is_integer_literal(expr: &Expr, value: u128) -> bool {
|
||||
// FIXME: use constant folding
|
||||
if let ExprKind::Lit(ref spanned) = expr.node {
|
||||
|
@ -706,7 +708,7 @@ pub fn is_adjusted(cx: &LateContext<'_, '_>, e: &Expr) -> bool {
|
|||
cx.tables.adjustments().get(e.hir_id).is_some()
|
||||
}
|
||||
|
||||
/// Return the pre-expansion span if is this comes from an expansion of the
|
||||
/// 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: &str) -> Option<Span> {
|
||||
|
@ -725,7 +727,7 @@ pub fn is_expn_of(mut span: Span, name: &str) -> Option<Span> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return the pre-expansion span if is this directly comes from an expansion
|
||||
/// Returns the pre-expansion span if is this directly comes from an expansion
|
||||
/// of the macro `name`.
|
||||
/// The difference with `is_expn_of` is that in
|
||||
/// ```rust,ignore
|
||||
|
@ -754,7 +756,7 @@ pub fn return_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, fn_item: hir::HirId) -> T
|
|||
cx.tcx.erase_late_bound_regions(&ret_ty)
|
||||
}
|
||||
|
||||
/// Check if two types are the same.
|
||||
/// Checks if two types are the same.
|
||||
///
|
||||
/// This discards any lifetime annotations, too.
|
||||
// FIXME: this works correctly for lifetimes bounds (`for <'a> Foo<'a>` == `for
|
||||
|
@ -768,7 +770,7 @@ pub fn same_tys<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, a: Ty<'tcx>, b: Ty<'tcx>)
|
|||
.enter(|infcx| infcx.can_eq(cx.param_env, a, b).is_ok())
|
||||
}
|
||||
|
||||
/// Return whether the given type is an `unsafe` function.
|
||||
/// Returns `true` if the given type is an `unsafe` function.
|
||||
pub fn type_is_unsafe_function<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
match ty.sty {
|
||||
ty::FnDef(..) | ty::FnPtr(_) => ty.fn_sig(cx.tcx).unsafety() == Unsafety::Unsafe,
|
||||
|
@ -780,7 +782,7 @@ pub fn is_copy<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
|
|||
ty.is_copy_modulo_regions(cx.tcx.global_tcx(), cx.param_env, DUMMY_SP)
|
||||
}
|
||||
|
||||
/// Return whether a pattern is refutable.
|
||||
/// Returns `true` if a pattern is refutable.
|
||||
pub fn is_refutable(cx: &LateContext<'_, '_>, pat: &Pat) -> bool {
|
||||
fn is_enum_variant(cx: &LateContext<'_, '_>, qpath: &QPath, id: HirId) -> bool {
|
||||
matches!(
|
||||
|
@ -869,7 +871,7 @@ pub fn iter_input_pats<'tcx>(decl: &FnDecl, body: &'tcx Body) -> impl Iterator<I
|
|||
(0..decl.inputs.len()).map(move |i| &body.arguments[i])
|
||||
}
|
||||
|
||||
/// Check if a given expression is a match expression
|
||||
/// Checks if a given expression is a match expression
|
||||
/// expanded from `?` operator or `try` macro.
|
||||
pub fn is_try<'a>(cx: &'_ LateContext<'_, '_>, expr: &'a Expr) -> Option<&'a Expr> {
|
||||
fn is_ok(cx: &'_ LateContext<'_, '_>, arm: &Arm) -> bool {
|
||||
|
@ -916,7 +918,7 @@ pub fn is_try<'a>(cx: &'_ LateContext<'_, '_>, expr: &'a Expr) -> Option<&'a Exp
|
|||
None
|
||||
}
|
||||
|
||||
/// Returns true if the lint is allowed in the current context
|
||||
/// Returns `true` if the lint is allowed in the current context
|
||||
///
|
||||
/// Useful for skipping long running code when it's unnecessary
|
||||
pub fn is_allowed(cx: &LateContext<'_, '_>, lint: &'static Lint, id: HirId) -> bool {
|
||||
|
@ -960,7 +962,7 @@ pub fn clip(tcx: TyCtxt<'_, '_, '_>, u: u128, ity: ast::UintTy) -> u128 {
|
|||
(u << amt) >> amt
|
||||
}
|
||||
|
||||
/// Remove block comments from the given Vec of lines
|
||||
/// Removes block comments from the given `Vec` of lines.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
@ -240,9 +240,9 @@ impl<'a> Sugg<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Add parenthesis to any expression that might need them. Suitable to the
|
||||
/// Adds parenthesis to any expression that might need them. Suitable to the
|
||||
/// `self` argument of
|
||||
/// a method call (eg. to build `bar.foo()` or `(1 + 2).foo()`).
|
||||
/// a method call (e.g., to build `bar.foo()` or `(1 + 2).foo()`).
|
||||
pub fn maybe_par(self) -> Self {
|
||||
match self {
|
||||
Sugg::NonParen(..) => self,
|
||||
|
@ -289,7 +289,7 @@ struct ParenHelper<T> {
|
|||
}
|
||||
|
||||
impl<T> ParenHelper<T> {
|
||||
/// Build a `ParenHelper`.
|
||||
/// Builds a `ParenHelper`.
|
||||
fn new(paren: bool, wrapped: T) -> Self {
|
||||
Self { paren, wrapped }
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ impl<T: Display> Display for ParenHelper<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Build the string for `<op><expr>` adding parenthesis when necessary.
|
||||
/// Builds the string for `<op><expr>` adding parenthesis when necessary.
|
||||
///
|
||||
/// For convenience, the operator is taken as a string because all unary
|
||||
/// operators have the same
|
||||
|
@ -314,7 +314,7 @@ pub fn make_unop(op: &str, expr: Sugg<'_>) -> Sugg<'static> {
|
|||
Sugg::MaybeParen(format!("{}{}", op, expr.maybe_par()).into())
|
||||
}
|
||||
|
||||
/// Build the string for `<lhs> <op> <rhs>` adding parenthesis when necessary.
|
||||
/// Builds the string for `<lhs> <op> <rhs>` adding parenthesis when necessary.
|
||||
///
|
||||
/// Precedence of shift operator relative to other arithmetic operation is
|
||||
/// often confusing so
|
||||
|
@ -413,7 +413,7 @@ enum Associativity {
|
|||
Right,
|
||||
}
|
||||
|
||||
/// Return the associativity/fixity of an operator. The difference with
|
||||
/// Returns the associativity/fixity of an operator. The difference with
|
||||
/// `AssocOp::fixity` is that
|
||||
/// an operator can be both left and right associative (such as `+`:
|
||||
/// `a + b + c == (a + b) + c == a + (b + c)`.
|
||||
|
@ -433,7 +433,7 @@ fn associativity(op: &AssocOp) -> Associativity {
|
|||
}
|
||||
}
|
||||
|
||||
/// Convert a `hir::BinOp` to the corresponding assigning binary operator.
|
||||
/// Converts a `hir::BinOp` to the corresponding assigning binary operator.
|
||||
fn hirbinop2assignop(op: hir::BinOp) -> AssocOp {
|
||||
use syntax::parse::token::BinOpToken::*;
|
||||
|
||||
|
@ -460,7 +460,7 @@ fn hirbinop2assignop(op: hir::BinOp) -> AssocOp {
|
|||
})
|
||||
}
|
||||
|
||||
/// Convert an `ast::BinOp` to the corresponding assigning binary operator.
|
||||
/// Converts an `ast::BinOp` to the corresponding assigning binary operator.
|
||||
fn astbinop2assignop(op: ast::BinOp) -> AssocOp {
|
||||
use syntax::ast::BinOpKind::*;
|
||||
use syntax::parse::token::BinOpToken;
|
||||
|
@ -480,13 +480,13 @@ fn astbinop2assignop(op: ast::BinOp) -> AssocOp {
|
|||
})
|
||||
}
|
||||
|
||||
/// Return the indentation before `span` if there are nothing but `[ \t]`
|
||||
/// Returns the indentation before `span` if there are nothing but `[ \t]`
|
||||
/// before it on its line.
|
||||
fn indentation<'a, T: LintContext<'a>>(cx: &T, span: Span) -> Option<String> {
|
||||
let lo = cx.sess().source_map().lookup_char_pos(span.lo());
|
||||
if let Some(line) = lo.file.get_line(lo.line - 1 /* line numbers in `Loc` are 1-based */) {
|
||||
if let Some((pos, _)) = line.char_indices().find(|&(_, c)| c != ' ' && c != '\t') {
|
||||
// we can mix char and byte positions here because we only consider `[ \t]`
|
||||
// We can mix char and byte positions here because we only consider `[ \t]`.
|
||||
if lo.col == CharPos(pos) {
|
||||
Some(line[..pos].into())
|
||||
} else {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use rustc::lint::LateContext;
|
||||
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::LateContext;
|
||||
use rustc::middle::expr_use_visitor::*;
|
||||
use rustc::middle::mem_categorization::cmt_;
|
||||
use rustc::middle::mem_categorization::Categorization;
|
||||
|
@ -9,7 +8,7 @@ use rustc::ty;
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
use syntax::source_map::Span;
|
||||
|
||||
/// Returns a set of mutated local variable ids or None if mutations could not be determined.
|
||||
/// Returns a set of mutated local variable IDs, or `None` if mutations could not be determined.
|
||||
pub fn mutated_variables<'a, 'tcx: 'a>(expr: &'tcx Expr, cx: &'a LateContext<'a, 'tcx>) -> Option<FxHashSet<HirId>> {
|
||||
let mut delegate = MutVarsDelegate {
|
||||
used_mutably: FxHashSet::default(),
|
||||
|
|
|
@ -106,7 +106,7 @@ fn check_vec_macro<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, vec_args: &higher::VecA
|
|||
);
|
||||
}
|
||||
|
||||
/// Return the item type of the vector (ie. the `T` in `Vec<T>`).
|
||||
/// Returns the item type of the vector (i.e., the `T` in `Vec<T>`).
|
||||
fn vec_type(ty: Ty<'_>) -> Ty<'_> {
|
||||
if let ty::Adt(_, substs) = ty.sty {
|
||||
substs.type_at(0)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#![allow(clippy::missing_docs_in_private_items)]
|
||||
|
||||
// FIXME: switch to something more ergonomic here, once available.
|
||||
// (currently there is no way to opt into sysroot crates w/o `extern crate`)
|
||||
// (Currently there is no way to opt into sysroot crates without `extern crate`.)
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate rustc_driver;
|
||||
#[allow(unused_extern_crates)]
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#![warn(rust_2018_idioms)]
|
||||
|
||||
// FIXME: switch to something more ergonomic here, once available.
|
||||
// (currently there is no way to opt into sysroot crates w/o `extern crate`)
|
||||
// (Currently there is no way to opt into sysroot crates without `extern crate`.)
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate rustc_driver;
|
||||
#[allow(unused_extern_crates)]
|
||||
|
|
|
@ -49,7 +49,7 @@ fn pred_test() {
|
|||
let v = 3;
|
||||
let sky = "blue";
|
||||
// this is a sneaky case, where the block isn't directly in the condition, but is actually
|
||||
// inside a closure that the condition is using. same principle applies. add some extra
|
||||
, andadd some extra
|
||||
// expressions to make sure linter isn't confused by them.
|
||||
if v == 3
|
||||
&& sky == "blue"
|
||||
|
|
|
@ -12,7 +12,7 @@ fn main() {
|
|||
(&1u8 as *const u8) as *const u16;
|
||||
(&mut 1u8 as *mut u8) as *mut u16;
|
||||
|
||||
/* These should be okay */
|
||||
/* These should be ok */
|
||||
|
||||
// not a pointer type
|
||||
1u8 as u16;
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
#![allow(clippy::no_effect)]
|
||||
|
||||
extern "C" {
|
||||
// NB. Mutability can be easily incorrect in FFI calls, as
|
||||
// in C, the default are mutable pointers.
|
||||
// N.B., mutability can be easily incorrect in FFI calls -- as
|
||||
// in C, the default is mutable pointers.
|
||||
fn ffi(c: *mut u8);
|
||||
fn int_ffi(c: *mut i32);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
///
|
||||
/// error[E0277]: the trait bound `T: Foo` is not satisfied
|
||||
///
|
||||
/// See https://github.com/rust-lang/rust-clippy/issues/2760
|
||||
// See rust-lang/rust-clippy#2760.
|
||||
|
||||
trait Foo {
|
||||
type Bar;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
/// See https://github.com/rust-lang/rust-clippy/issues/2774
|
||||
// See rust-lang/rust-clippy#2774.
|
||||
|
||||
#[derive(Eq, PartialEq, Debug, Hash)]
|
||||
pub struct Bar {
|
||||
|
@ -11,14 +11,14 @@ pub struct Bar {
|
|||
pub struct Foo {}
|
||||
|
||||
#[allow(clippy::implicit_hasher)]
|
||||
// This should not cause a 'cannot relate bound region' ICE
|
||||
// This should not cause a "cannot relate bound region" ICE.
|
||||
pub fn add_barfoos_to_foos<'a>(bars: &HashSet<&'a Bar>) {
|
||||
let mut foos = HashSet::new();
|
||||
foos.extend(bars.iter().map(|b| &b.foo));
|
||||
}
|
||||
|
||||
#[allow(clippy::implicit_hasher)]
|
||||
// Also this should not cause a 'cannot relate bound region' ICE
|
||||
// Also, this should not cause a "cannot relate bound region" ICE.
|
||||
pub fn add_barfoos_to_foos2(bars: &HashSet<&Bar>) {
|
||||
let mut foos = HashSet::new();
|
||||
foos.extend(bars.iter().map(|b| &b.foo));
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
/// Test that we do not lint for unused underscores in a `MacroAttribute`
|
||||
/// Tests that we do not lint for unused underscores in a `MacroAttribute`
|
||||
/// expansion
|
||||
#[deny(clippy::used_underscore_binding)]
|
||||
#[derive(Deserialize)]
|
||||
|
|
|
@ -12,7 +12,7 @@ trait Foo {
|
|||
const BAR: Option<LinkedList<u8>>;
|
||||
}
|
||||
|
||||
// ok, we don’t want to warn for implementations, see #605
|
||||
// Ok, we don’t want to warn for implementations; see issue #605.
|
||||
impl Foo for LinkedList<u8> {
|
||||
fn foo(_: LinkedList<u8>) {}
|
||||
const BAR: Option<LinkedList<u8>> = None;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//! This file tests for the DOC_MARKDOWN lint
|
||||
//! This file tests for the `DOC_MARKDOWN` lint.
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![warn(clippy::doc_markdown)]
|
||||
|
@ -6,7 +6,7 @@
|
|||
#![rustfmt::skip]
|
||||
|
||||
/// The foo_bar function does _nothing_. See also foo::bar. (note the dot there)
|
||||
/// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not Foo::some_fun
|
||||
/// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not Foo::some_fun
|
||||
/// which should be reported only once despite being __doubly bad__.
|
||||
/// Here be ::a::global:path.
|
||||
/// That's not code ~NotInCodeBlock~.
|
||||
|
@ -71,7 +71,7 @@ fn main() {
|
|||
}
|
||||
|
||||
/// ## CamelCaseThing
|
||||
/// Talks about `CamelCaseThing`. Titles should be ignored, see issue #897.
|
||||
/// Talks about `CamelCaseThing`. Titles should be ignored; see issue #897.
|
||||
///
|
||||
/// # CamelCaseThing
|
||||
///
|
||||
|
@ -107,7 +107,7 @@ fn issue883() {
|
|||
fn multiline() {
|
||||
}
|
||||
|
||||
/** E.g. serialization of an empty list: FooBar
|
||||
/** E.g., serialization of an empty list: FooBar
|
||||
```
|
||||
That's in a code block: `PackedNode`
|
||||
```
|
||||
|
@ -118,7 +118,7 @@ be_sure_we_got_to_the_end_of_it
|
|||
fn issue1073() {
|
||||
}
|
||||
|
||||
/** E.g. serialization of an empty list: FooBar
|
||||
/** E.g., serialization of an empty list: FooBar
|
||||
```
|
||||
That's in a code block: PackedNode
|
||||
```
|
||||
|
@ -129,7 +129,7 @@ be_sure_we_got_to_the_end_of_it
|
|||
fn issue1073_alt() {
|
||||
}
|
||||
|
||||
/// Test more than three quotes:
|
||||
/// Tests more than three quotes:
|
||||
/// ````
|
||||
/// DoNotWarn
|
||||
/// ```
|
||||
|
|
|
@ -21,7 +21,7 @@ LL | /// The foo_bar function does _nothing_. See also foo::bar. (note the dot t
|
|||
error: you should put `Foo::some_fun` between ticks in the documentation
|
||||
--> $DIR/doc.rs:9:84
|
||||
|
|
||||
LL | /// Markdown is _weird_. I mean _really weird_. This /_ is ok. So is `_`. But not Foo::some_fun
|
||||
LL | /, andThis /_ is ok. So is `_`. But not Foo::some_fun
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: you should put `a::global:path` between ticks in the documentation
|
||||
|
|
|
@ -13,44 +13,44 @@ fn main() {
|
|||
format!("foo");
|
||||
|
||||
format!("{}", "foo");
|
||||
format!("{:?}", "foo"); // don't warn about debug
|
||||
format!("{:?}", "foo"); // Don't warn about `Debug`.
|
||||
format!("{:8}", "foo");
|
||||
format!("{:width$}", "foo", width = 8);
|
||||
format!("{:+}", "foo"); // warn when the format makes no difference
|
||||
format!("{:<}", "foo"); // warn when the format makes no difference
|
||||
format!("{:+}", "foo"); // Warn when the format makes no difference.
|
||||
format!("{:<}", "foo"); // Warn when the format makes no difference.
|
||||
format!("foo {}", "bar");
|
||||
format!("{} bar", "foo");
|
||||
|
||||
let arg: String = "".to_owned();
|
||||
format!("{}", arg);
|
||||
format!("{:?}", arg); // don't warn about debug
|
||||
format!("{:?}", arg); // Don't warn about debug.
|
||||
format!("{:8}", arg);
|
||||
format!("{:width$}", arg, width = 8);
|
||||
format!("{:+}", arg); // warn when the format makes no difference
|
||||
format!("{:<}", arg); // warn when the format makes no difference
|
||||
format!("{:+}", arg); // Warn when the format makes no difference.
|
||||
format!("{:<}", arg); // Warn when the format makes no difference.
|
||||
format!("foo {}", arg);
|
||||
format!("{} bar", arg);
|
||||
|
||||
// we don’t want to warn for non-string args, see #697
|
||||
// We don’t want to warn for non-string args; see issue #697.
|
||||
format!("{}", 42);
|
||||
format!("{:?}", 42);
|
||||
format!("{:+}", 42);
|
||||
format!("foo {}", 42);
|
||||
format!("{} bar", 42);
|
||||
|
||||
// we only want to warn about `format!` itself
|
||||
// We only want to warn about `format!` itself.
|
||||
println!("foo");
|
||||
println!("{}", "foo");
|
||||
println!("foo {}", "foo");
|
||||
println!("{}", 42);
|
||||
println!("foo {}", 42);
|
||||
|
||||
// A format! inside a macro should not trigger a warning
|
||||
// A `format!` inside a macro should not trigger a warning.
|
||||
foo!("should not warn");
|
||||
|
||||
// precision on string means slicing without panicking on size:
|
||||
format!("{:.1}", "foo"); // could be "foo"[..1]
|
||||
format!("{:.10}", "foo"); // could not be "foo"[..10]
|
||||
// Precision on string means slicing without panicking on size.
|
||||
format!("{:.1}", "foo"); // could be `"foo"[..1]`
|
||||
format!("{:.10}", "foo"); // could not be `"foo"[..10]`
|
||||
format!("{:.prec$}", "foo", prec = 1);
|
||||
format!("{:.prec$}", "foo", prec = 10);
|
||||
|
||||
|
|
|
@ -232,7 +232,7 @@ fn if_same_then_else() -> Result<&'static str, ()> {
|
|||
return Ok(&foo[0..]);
|
||||
}
|
||||
|
||||
// false positive if_same_then_else, let(x,y) vs let(y,x), see #3559
|
||||
// False positive `if_same_then_else`: `let (x, y)` vs. `let (y, x)`; see issue #3559.
|
||||
if true {
|
||||
let foo = "";
|
||||
let (x, y) = (1, 2);
|
||||
|
@ -244,7 +244,7 @@ fn if_same_then_else() -> Result<&'static str, ()> {
|
|||
}
|
||||
}
|
||||
|
||||
// Issue #2423. This was causing an ICE
|
||||
// Issue #2423. This was causing an ICE.
|
||||
fn func() {
|
||||
if true {
|
||||
f(&[0; 62]);
|
||||
|
|
|
@ -10,13 +10,13 @@ impl PubOne {
|
|||
}
|
||||
|
||||
impl PubOne {
|
||||
// A second impl for this struct - the error span shouldn't mention this
|
||||
// A second impl for this struct -- the error span shouldn't mention this.
|
||||
pub fn irrelevant(self: &Self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
// Identical to PubOne, but with an allow attribute on the impl complaining len
|
||||
// Identical to `PubOne`, but with an `allow` attribute on the impl complaining `len`.
|
||||
pub struct PubAllowed;
|
||||
|
||||
#[allow(clippy::len_without_is_empty)]
|
||||
|
@ -26,8 +26,8 @@ impl PubAllowed {
|
|||
}
|
||||
}
|
||||
|
||||
// No allow attribute on this impl block, but that doesn't matter - we only require one on the
|
||||
// impl containing len.
|
||||
// No `allow` attribute on this impl block, but that doesn't matter -- we only require one on the
|
||||
// impl containing `len`.
|
||||
impl PubAllowed {
|
||||
pub fn irrelevant(self: &Self) -> bool {
|
||||
false
|
||||
|
@ -38,7 +38,7 @@ struct NotPubOne;
|
|||
|
||||
impl NotPubOne {
|
||||
pub fn len(self: &Self) -> isize {
|
||||
// no error, len is pub but `NotPubOne` is not exported anyway
|
||||
// No error; `len` is pub but `NotPubOne` is not exported anyway.
|
||||
1
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ struct One;
|
|||
|
||||
impl One {
|
||||
fn len(self: &Self) -> isize {
|
||||
// no error, len is private, see #1085
|
||||
// No error; `len` is private; see issue #1085.
|
||||
1
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,8 @@ impl PubTraitsToo for One {
|
|||
}
|
||||
|
||||
trait TraitsToo {
|
||||
fn len(self: &Self) -> isize; // no error, len is private, see #1085
|
||||
fn len(self: &Self) -> isize;
|
||||
// No error; `len` is private; see issue #1085.
|
||||
}
|
||||
|
||||
impl TraitsToo for One {
|
||||
|
@ -130,7 +131,7 @@ pub trait Empty {
|
|||
}
|
||||
|
||||
pub trait InheritingEmpty: Empty {
|
||||
//must not trigger LEN_WITHOUT_IS_EMPTY
|
||||
// Must not trigger `LEN_WITHOUT_IS_EMPTY`.
|
||||
fn len(&self) -> isize;
|
||||
}
|
||||
|
||||
|
@ -144,13 +145,13 @@ fn main() {
|
|||
|
||||
let y = One;
|
||||
if y.len() == 0 {
|
||||
//no error because One does not have .is_empty()
|
||||
// No error; `One` does not have `.is_empty()`.
|
||||
println!("This should not happen either!");
|
||||
}
|
||||
|
||||
let z: &TraitsToo = &y;
|
||||
if z.len() > 0 {
|
||||
//no error, because TraitsToo has no .is_empty() method
|
||||
// No error; `TraitsToo` has no `.is_empty()` method.
|
||||
println!("Nor should this!");
|
||||
}
|
||||
|
||||
|
@ -171,11 +172,11 @@ fn main() {
|
|||
println!("Or this!");
|
||||
}
|
||||
if has_is_empty.len() > 1 {
|
||||
// no error
|
||||
// No error.
|
||||
println!("This can happen.");
|
||||
}
|
||||
if has_is_empty.len() <= 1 {
|
||||
// no error
|
||||
// No error.
|
||||
println!("This can happen.");
|
||||
}
|
||||
if 0 == has_is_empty.len() {
|
||||
|
@ -194,11 +195,11 @@ fn main() {
|
|||
println!("Or this!");
|
||||
}
|
||||
if 1 < has_is_empty.len() {
|
||||
// no error
|
||||
// No error.
|
||||
println!("This can happen.");
|
||||
}
|
||||
if 1 >= has_is_empty.len() {
|
||||
// no error
|
||||
// No error.
|
||||
println!("This can happen.");
|
||||
}
|
||||
assert!(!has_is_empty.is_empty());
|
||||
|
@ -211,7 +212,7 @@ fn main() {
|
|||
|
||||
let has_wrong_is_empty = HasWrongIsEmpty;
|
||||
if has_wrong_is_empty.len() == 0 {
|
||||
//no error as HasWrongIsEmpty does not have .is_empty()
|
||||
// No error; `HasWrongIsEmpty` does not have `.is_empty()`.
|
||||
println!("Or this!");
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +221,7 @@ fn test_slice(b: &[u8]) {
|
|||
if b.len() != 0 {}
|
||||
}
|
||||
|
||||
// this used to ICE
|
||||
// This used to ICE.
|
||||
pub trait Foo: Sized {}
|
||||
|
||||
pub trait DependsOnFoo: Foo {
|
||||
|
|
|
@ -5,9 +5,11 @@ fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {}
|
|||
|
||||
fn distinct_and_static<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: &'static u8) {}
|
||||
|
||||
fn same_lifetime_on_input<'a>(_x: &'a u8, _y: &'a u8) {} // no error, same lifetime on two params
|
||||
// No error; same lifetime on two params.
|
||||
fn same_lifetime_on_input<'a>(_x: &'a u8, _y: &'a u8) {}
|
||||
|
||||
fn only_static_on_input(_x: &u8, _y: &u8, _z: &'static u8) {} // no error, static involved
|
||||
// No error; static involved.
|
||||
fn only_static_on_input(_x: &u8, _y: &u8, _z: &'static u8) {}
|
||||
|
||||
fn mut_and_static_input(_x: &mut u8, _y: &'static str) {}
|
||||
|
||||
|
@ -15,31 +17,36 @@ fn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 {
|
|||
x
|
||||
}
|
||||
|
||||
// No error; multiple input refs.
|
||||
fn multiple_in_and_out_1<'a>(x: &'a u8, _y: &'a u8) -> &'a u8 {
|
||||
x
|
||||
} // no error, multiple input refs
|
||||
}
|
||||
|
||||
// No error; multiple input refs.
|
||||
fn multiple_in_and_out_2<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 {
|
||||
x
|
||||
} // no error, multiple input refs
|
||||
}
|
||||
|
||||
// No error; static involved.
|
||||
fn in_static_and_out<'a>(x: &'a u8, _y: &'static u8) -> &'a u8 {
|
||||
x
|
||||
} // no error, static involved
|
||||
}
|
||||
|
||||
// No error.
|
||||
fn deep_reference_1<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> {
|
||||
Ok(x)
|
||||
} // no error
|
||||
}
|
||||
|
||||
// No error; two input refs.
|
||||
fn deep_reference_2<'a>(x: Result<&'a u8, &'a u8>) -> &'a u8 {
|
||||
x.unwrap()
|
||||
} // no error, two input refs
|
||||
}
|
||||
|
||||
fn deep_reference_3<'a>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> {
|
||||
Ok(x)
|
||||
}
|
||||
|
||||
// where clause, but without lifetimes
|
||||
// Where-clause, but without lifetimes.
|
||||
fn where_clause_without_lt<'a, T>(x: &'a u8, _y: u8) -> Result<&'a u8, ()>
|
||||
where
|
||||
T: Copy,
|
||||
|
@ -49,25 +56,29 @@ where
|
|||
|
||||
type Ref<'r> = &'r u8;
|
||||
|
||||
fn lifetime_param_1<'a>(_x: Ref<'a>, _y: &'a u8) {} // no error, same lifetime on two params
|
||||
// No error; same lifetime on two params.
|
||||
fn lifetime_param_1<'a>(_x: Ref<'a>, _y: &'a u8) {}
|
||||
|
||||
fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {}
|
||||
|
||||
fn lifetime_param_3<'a, 'b: 'a>(_x: Ref<'a>, _y: &'b u8) {} // no error, bounded lifetime
|
||||
// No error; bounded lifetime.
|
||||
fn lifetime_param_3<'a, 'b: 'a>(_x: Ref<'a>, _y: &'b u8) {}
|
||||
|
||||
// No error; bounded lifetime.
|
||||
fn lifetime_param_4<'a, 'b>(_x: Ref<'a>, _y: &'b u8)
|
||||
where
|
||||
'b: 'a,
|
||||
{
|
||||
} // no error, bounded lifetime
|
||||
}
|
||||
|
||||
struct Lt<'a, I: 'static> {
|
||||
x: &'a I,
|
||||
}
|
||||
|
||||
// No error; fn bound references `'a`.
|
||||
fn fn_bound<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>
|
||||
where
|
||||
F: Fn(Lt<'a, I>) -> Lt<'a, I>, // no error, fn bound references 'a
|
||||
F: Fn(Lt<'a, I>) -> Lt<'a, I>,
|
||||
{
|
||||
unreachable!()
|
||||
}
|
||||
|
@ -79,8 +90,8 @@ where
|
|||
unreachable!()
|
||||
}
|
||||
|
||||
// No error; see below.
|
||||
fn fn_bound_3<'a, F: FnOnce(&'a i32)>(x: &'a i32, f: F) {
|
||||
// no error, see below
|
||||
f(x);
|
||||
}
|
||||
|
||||
|
@ -88,10 +99,11 @@ fn fn_bound_3_cannot_elide() {
|
|||
let x = 42;
|
||||
let p = &x;
|
||||
let mut q = &x;
|
||||
fn_bound_3(p, |y| q = y); // this will fail if we elides lifetimes of `fn_bound_3`
|
||||
// This will fail if we elide lifetimes of `fn_bound_3`.
|
||||
fn_bound_3(p, |y| q = y);
|
||||
}
|
||||
|
||||
// no error, multiple input refs
|
||||
// No error; multiple input refs.
|
||||
fn fn_bound_4<'a, F: FnOnce() -> &'a ()>(cond: bool, x: &'a (), f: F) -> &'a () {
|
||||
if cond {
|
||||
x
|
||||
|
@ -109,20 +121,24 @@ impl X {
|
|||
&self.x
|
||||
}
|
||||
|
||||
// No error; multiple input refs.
|
||||
fn self_and_in_out<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 {
|
||||
&self.x
|
||||
} // no error, multiple input refs
|
||||
}
|
||||
|
||||
fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) {}
|
||||
|
||||
fn self_and_same_in<'s>(&'s self, _x: &'s u8) {} // no error, same lifetimes on two params
|
||||
// No error; same lifetimes on two params.
|
||||
fn self_and_same_in<'s>(&'s self, _x: &'s u8) {}
|
||||
}
|
||||
|
||||
struct Foo<'a>(&'a u8);
|
||||
|
||||
impl<'a> Foo<'a> {
|
||||
fn self_shared_lifetime(&self, _: &'a u8) {} // no error, lifetime 'a not defined in method
|
||||
fn self_bound_lifetime<'b: 'a>(&self, _: &'b u8) {} // no error, bounds exist
|
||||
// No error; lifetime `'a` not defined in method.
|
||||
fn self_shared_lifetime(&self, _: &'a u8) {}
|
||||
// No error; bounds exist.
|
||||
fn self_bound_lifetime<'b: 'a>(&self, _: &'b u8) {}
|
||||
}
|
||||
|
||||
fn already_elided<'a>(_: &u8, _: &'a u8) -> &'a u8 {
|
||||
|
@ -133,17 +149,17 @@ fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str {
|
|||
unimplemented!()
|
||||
}
|
||||
|
||||
// no warning, two input lifetimes (named on the reference, anonymous on Foo)
|
||||
// No warning; two input lifetimes (named on the reference, anonymous on `Foo`).
|
||||
fn struct_with_lt2<'a>(_foo: &'a Foo) -> &'a str {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// no warning, two input lifetimes (anonymous on the reference, named on Foo)
|
||||
// No warning; two input lifetimes (anonymous on the reference, named on `Foo`).
|
||||
fn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// no warning, two input lifetimes
|
||||
// No warning; two input lifetimes.
|
||||
fn struct_with_lt4<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {
|
||||
unimplemented!()
|
||||
}
|
||||
|
@ -152,13 +168,13 @@ trait WithLifetime<'a> {}
|
|||
|
||||
type WithLifetimeAlias<'a> = WithLifetime<'a>;
|
||||
|
||||
// should not warn because it won't build without the lifetime
|
||||
// Should not warn because it won't build without the lifetime.
|
||||
fn trait_obj_elided<'a>(_arg: &'a WithLifetime) -> &'a str {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// this should warn because there is no lifetime on Drop, so this would be
|
||||
// unambiguous if we elided the lifetime
|
||||
// Should warn because there is no lifetime on `Drop`, so this would be
|
||||
// unambiguous if we elided the lifetime.
|
||||
fn trait_obj_elided2<'a>(_arg: &'a Drop) -> &'a str {
|
||||
unimplemented!()
|
||||
}
|
||||
|
@ -169,17 +185,17 @@ fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str {
|
|||
unimplemented!()
|
||||
}
|
||||
|
||||
// no warning, two input lifetimes (named on the reference, anonymous on Foo)
|
||||
// No warning; two input lifetimes (named on the reference, anonymous on `FooAlias`).
|
||||
fn alias_with_lt2<'a>(_foo: &'a FooAlias) -> &'a str {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// no warning, two input lifetimes (anonymous on the reference, named on Foo)
|
||||
// No warning; two input lifetimes (anonymous on the reference, named on `FooAlias`).
|
||||
fn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// no warning, two input lifetimes
|
||||
// No warning; two input lifetimes.
|
||||
fn alias_with_lt4<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {
|
||||
unimplemented!()
|
||||
}
|
||||
|
@ -199,12 +215,12 @@ fn trait_bound<'a, T: WithLifetime<'a>>(_: &'a u8, _: T) {
|
|||
unimplemented!()
|
||||
}
|
||||
|
||||
// don't warn on these, see #292
|
||||
// Don't warn on these; see issue #292.
|
||||
fn trait_bound_bug<'a, T: WithLifetime<'a>>() {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// #740
|
||||
// See issue #740.
|
||||
struct Test {
|
||||
vec: Vec<usize>,
|
||||
}
|
||||
|
@ -224,8 +240,7 @@ fn test<'a>(x: &'a [u8]) -> u8 {
|
|||
*y
|
||||
}
|
||||
|
||||
// #3284 - Give a hint regarding lifetime in return type
|
||||
|
||||
// Issue #3284: give hint regarding lifetime in return type.
|
||||
struct Cow<'a> {
|
||||
x: &'a str,
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ fn ref_pats() {
|
|||
&None => println!("none"),
|
||||
}
|
||||
match v {
|
||||
// this doesn't trigger, we have a different pattern
|
||||
// This doesn't trigger; we have a different pattern.
|
||||
&Some(v) => println!("some"),
|
||||
other => println!("other"),
|
||||
}
|
||||
|
@ -23,13 +23,13 @@ fn ref_pats() {
|
|||
&(v, 1) => println!("{}", v),
|
||||
_ => println!("none"),
|
||||
}
|
||||
// special case: using & both in expr and pats
|
||||
// Special case: using `&` both in expr and pats.
|
||||
let w = Some(0);
|
||||
match &w {
|
||||
&Some(v) => println!("{:?}", v),
|
||||
&None => println!("none"),
|
||||
}
|
||||
// false positive: only wildcard pattern
|
||||
// False positive: only wildcard pattern.
|
||||
let w = Some(0);
|
||||
match w {
|
||||
_ => println!("none"),
|
||||
|
@ -69,14 +69,14 @@ fn match_wild_err_arm() {
|
|||
},
|
||||
}
|
||||
|
||||
// allowed when not with `panic!` block
|
||||
// Allowed when not with `panic!` block.
|
||||
match x {
|
||||
Ok(3) => println!("ok"),
|
||||
Ok(_) => println!("ok"),
|
||||
Err(_) => println!("err"),
|
||||
}
|
||||
|
||||
// allowed when used with `unreachable!`
|
||||
// Allowed when used with `unreachable!`.
|
||||
match x {
|
||||
Ok(3) => println!("ok"),
|
||||
Ok(_) => println!("ok"),
|
||||
|
@ -97,14 +97,14 @@ fn match_wild_err_arm() {
|
|||
},
|
||||
}
|
||||
|
||||
// no warning because of the guard
|
||||
// No warning because of the guard.
|
||||
match x {
|
||||
Ok(x) if x * x == 64 => println!("ok"),
|
||||
Ok(_) => println!("ok"),
|
||||
Err(_) => println!("err"),
|
||||
}
|
||||
|
||||
// this used to be a false positive, see #1996
|
||||
// This used to be a false positive; see issue #1996.
|
||||
match x {
|
||||
Ok(3) => println!("ok"),
|
||||
Ok(x) if x * x == 64 => println!("ok 64"),
|
||||
|
@ -118,14 +118,14 @@ fn match_wild_err_arm() {
|
|||
_ => println!("err"),
|
||||
}
|
||||
|
||||
// no warning because of the different types for x
|
||||
// No warning; different types for `x`.
|
||||
match (x, Some(1.0f64)) {
|
||||
(Ok(x), Some(_)) => println!("ok {}", x),
|
||||
(Ok(_), Some(x)) => println!("ok {}", x),
|
||||
_ => println!("err"),
|
||||
}
|
||||
|
||||
// because of a bug, no warning was generated for this case before #2251
|
||||
// Because of a bug, no warning was generated for this case before #2251.
|
||||
match x {
|
||||
Ok(_tmp) => println!("ok"),
|
||||
Ok(3) => println!("ok"),
|
||||
|
|
|
@ -49,19 +49,20 @@ impl T {
|
|||
true
|
||||
}
|
||||
|
||||
// no error, self is a ref
|
||||
// No error; self is a ref.
|
||||
fn sub(&self, other: T) -> &T {
|
||||
self
|
||||
}
|
||||
|
||||
// no error, different #arguments
|
||||
// No error; different number of arguments.
|
||||
fn div(self) -> T {
|
||||
self
|
||||
}
|
||||
|
||||
fn rem(self, other: T) {} // no error, wrong return type
|
||||
// No error; wrong return type.
|
||||
fn rem(self, other: T) {}
|
||||
|
||||
// fine
|
||||
// Fine
|
||||
fn into_u32(self) -> u32 {
|
||||
0
|
||||
}
|
||||
|
@ -84,7 +85,7 @@ struct Lt<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Lt<'a> {
|
||||
// The lifetime is different, but that’s irrelevant, see #734
|
||||
// The lifetime is different, but that’s irrelevant; see issue #734.
|
||||
#[allow(clippy::needless_lifetimes)]
|
||||
pub fn new<'b>(s: &'b str) -> Lt<'b> {
|
||||
unimplemented!()
|
||||
|
@ -96,7 +97,7 @@ struct Lt2<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Lt2<'a> {
|
||||
// The lifetime is different, but that’s irrelevant, see #734
|
||||
// The lifetime is different, but that’s irrelevant; see issue #734.
|
||||
pub fn new(s: &str) -> Lt2 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
@ -107,7 +108,7 @@ struct Lt3<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Lt3<'a> {
|
||||
// The lifetime is different, but that’s irrelevant, see #734
|
||||
// The lifetime is different, but that’s irrelevant; see issue #734.
|
||||
pub fn new() -> Lt3<'static> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
@ -120,7 +121,7 @@ impl U {
|
|||
fn new() -> Self {
|
||||
U
|
||||
}
|
||||
// ok because U is Copy
|
||||
// Ok because `U` is `Copy`.
|
||||
fn to_something(self) -> u32 {
|
||||
0
|
||||
}
|
||||
|
@ -138,7 +139,7 @@ impl<T> V<T> {
|
|||
|
||||
impl Mul<T> for T {
|
||||
type Output = T;
|
||||
// no error, obviously
|
||||
// No error, obviously.
|
||||
fn mul(self, other: T) -> T {
|
||||
self
|
||||
}
|
||||
|
@ -152,12 +153,12 @@ impl Mul<T> for T {
|
|||
fn option_methods() {
|
||||
let opt = Some(1);
|
||||
|
||||
// Check OPTION_MAP_UNWRAP_OR
|
||||
// single line case
|
||||
// Check `OPTION_MAP_UNWRAP_OR`.
|
||||
// Single line case.
|
||||
let _ = opt.map(|x| x + 1)
|
||||
|
||||
.unwrap_or(0); // should lint even though this call is on a separate line
|
||||
// multi line cases
|
||||
// Should lint even though this call is on a separate line.
|
||||
.unwrap_or(0);
|
||||
// Multi-line cases.
|
||||
let _ = opt.map(|x| {
|
||||
x + 1
|
||||
}
|
||||
|
@ -166,9 +167,9 @@ fn option_methods() {
|
|||
.unwrap_or({
|
||||
0
|
||||
});
|
||||
// single line `map(f).unwrap_or(None)` case
|
||||
// Single line `map(f).unwrap_or(None)` case.
|
||||
let _ = opt.map(|x| Some(x + 1)).unwrap_or(None);
|
||||
// multiline `map(f).unwrap_or(None)` cases
|
||||
// Multi-line `map(f).unwrap_or(None)` cases.
|
||||
let _ = opt.map(|x| {
|
||||
Some(x + 1)
|
||||
}
|
||||
|
@ -189,9 +190,9 @@ fn option_methods() {
|
|||
// Check OPTION_MAP_UNWRAP_OR_ELSE
|
||||
// single line case
|
||||
let _ = opt.map(|x| x + 1)
|
||||
|
||||
.unwrap_or_else(|| 0); // should lint even though this call is on a separate line
|
||||
// multi line cases
|
||||
// Should lint even though this call is on a separate line.
|
||||
.unwrap_or_else(|| 0);
|
||||
// Multi-line cases.
|
||||
let _ = opt.map(|x| {
|
||||
x + 1
|
||||
}
|
||||
|
@ -200,20 +201,21 @@ fn option_methods() {
|
|||
.unwrap_or_else(||
|
||||
0
|
||||
);
|
||||
// macro case
|
||||
let _ = opt_map!(opt, |x| x + 1).unwrap_or_else(|| 0); // should not lint
|
||||
// Macro case.
|
||||
// Should not lint.
|
||||
let _ = opt_map!(opt, |x| x + 1).unwrap_or_else(|| 0);
|
||||
|
||||
// Check OPTION_MAP_OR_NONE
|
||||
// single line case
|
||||
// Check `OPTION_MAP_OR_NONE`.
|
||||
// Single line case.
|
||||
let _ = opt.map_or(None, |x| Some(x + 1));
|
||||
// multi line case
|
||||
// Multi-line case.
|
||||
let _ = opt.map_or(None, |x| {
|
||||
Some(x + 1)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/// Struct to generate false positives for things with .iter()
|
||||
/// Struct to generate false positives for things with `.iter()`.
|
||||
#[derive(Copy, Clone)]
|
||||
struct HasIter;
|
||||
|
||||
|
@ -227,65 +229,65 @@ impl HasIter {
|
|||
}
|
||||
}
|
||||
|
||||
/// Checks implementation of `FILTER_NEXT` lint
|
||||
/// Checks implementation of `FILTER_NEXT` lint.
|
||||
#[rustfmt::skip]
|
||||
fn filter_next() {
|
||||
let v = vec![3, 2, 1, 0, -1, -2, -3];
|
||||
|
||||
// check single-line case
|
||||
// Single-line case.
|
||||
let _ = v.iter().filter(|&x| *x < 0).next();
|
||||
|
||||
// check multi-line case
|
||||
// Multi-line case.
|
||||
let _ = v.iter().filter(|&x| {
|
||||
*x < 0
|
||||
}
|
||||
).next();
|
||||
|
||||
// check that we don't lint if the caller is not an Iterator
|
||||
// Check that hat we don't lint if the caller is not an `Iterator`.
|
||||
let foo = IteratorFalsePositives { foo: 0 };
|
||||
let _ = foo.filter().next();
|
||||
}
|
||||
|
||||
/// Checks implementation of `SEARCH_IS_SOME` lint
|
||||
/// Checks implementation of `SEARCH_IS_SOME` lint.
|
||||
#[rustfmt::skip]
|
||||
fn search_is_some() {
|
||||
let v = vec![3, 2, 1, 0, -1, -2, -3];
|
||||
|
||||
// check `find().is_some()`, single-line
|
||||
// Check `find().is_some()`, single-line case.
|
||||
let _ = v.iter().find(|&x| *x < 0).is_some();
|
||||
|
||||
// check `find().is_some()`, multi-line
|
||||
// Check `find().is_some()`, multi-line case.
|
||||
let _ = v.iter().find(|&x| {
|
||||
*x < 0
|
||||
}
|
||||
).is_some();
|
||||
|
||||
// check `position().is_some()`, single-line
|
||||
// Check `position().is_some()`, single-line case.
|
||||
let _ = v.iter().position(|&x| x < 0).is_some();
|
||||
|
||||
// check `position().is_some()`, multi-line
|
||||
// Check `position().is_some()`, multi-line case.
|
||||
let _ = v.iter().position(|&x| {
|
||||
x < 0
|
||||
}
|
||||
).is_some();
|
||||
|
||||
// check `rposition().is_some()`, single-line
|
||||
// Check `rposition().is_some()`, single-line case.
|
||||
let _ = v.iter().rposition(|&x| x < 0).is_some();
|
||||
|
||||
// check `rposition().is_some()`, multi-line
|
||||
// Check `rposition().is_some()`, multi-line case.
|
||||
let _ = v.iter().rposition(|&x| {
|
||||
x < 0
|
||||
}
|
||||
).is_some();
|
||||
|
||||
// check that we don't lint if the caller is not an Iterator
|
||||
// Check that we don't lint if the caller is not an `Iterator`.
|
||||
let foo = IteratorFalsePositives { foo: 0 };
|
||||
let _ = foo.find().is_some();
|
||||
let _ = foo.position().is_some();
|
||||
let _ = foo.rposition().is_some();
|
||||
}
|
||||
|
||||
/// Checks implementation of the `OR_FUN_CALL` lint
|
||||
/// Checks implementation of the `OR_FUN_CALL` lint.
|
||||
fn or_fun_call() {
|
||||
struct Foo;
|
||||
|
||||
|
@ -348,14 +350,14 @@ fn or_fun_call() {
|
|||
let _ = stringy.unwrap_or("".to_owned());
|
||||
}
|
||||
|
||||
/// Checks implementation of `ITER_NTH` lint
|
||||
/// Checks implementation of `ITER_NTH` lint.
|
||||
fn iter_nth() {
|
||||
let mut some_vec = vec![0, 1, 2, 3];
|
||||
let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);
|
||||
let mut some_vec_deque: VecDeque<_> = some_vec.iter().cloned().collect();
|
||||
|
||||
{
|
||||
// Make sure we lint `.iter()` for relevant types
|
||||
// Make sure we lint `.iter()` for relevant types.
|
||||
let bad_vec = some_vec.iter().nth(3);
|
||||
let bad_slice = &some_vec[..].iter().nth(3);
|
||||
let bad_boxed_slice = boxed_slice.iter().nth(3);
|
||||
|
@ -363,7 +365,7 @@ fn iter_nth() {
|
|||
}
|
||||
|
||||
{
|
||||
// Make sure we lint `.iter_mut()` for relevant types
|
||||
// Make sure we lint `.iter_mut()` for relevant types.
|
||||
let bad_vec = some_vec.iter_mut().nth(3);
|
||||
}
|
||||
{
|
||||
|
@ -373,7 +375,7 @@ fn iter_nth() {
|
|||
let bad_vec_deque = some_vec_deque.iter_mut().nth(3);
|
||||
}
|
||||
|
||||
// Make sure we don't lint for non-relevant types
|
||||
// Make sure we don't lint for non-relevant types.
|
||||
let false_positive = HasIter;
|
||||
let ok = false_positive.iter().nth(3);
|
||||
let ok_mut = false_positive.iter_mut().nth(3);
|
||||
|
|
|
@ -14,12 +14,12 @@ fn main() {
|
|||
let mut var2 = 5;
|
||||
let thingy2 = Some(&mut var2);
|
||||
if let Some(&mut ref mut v) = thingy2 {
|
||||
// ^ should *not* be linted
|
||||
// ^ should **not** be linted
|
||||
// v is borrowed as mutable.
|
||||
*v = 10;
|
||||
}
|
||||
if let Some(&mut ref v) = thingy2 {
|
||||
// ^ should *not* be linted
|
||||
// ^ should **not** be linted
|
||||
// here, v is borrowed as immutable.
|
||||
// can't do that:
|
||||
//*v = 15;
|
||||
|
@ -37,7 +37,7 @@ enum Animal {
|
|||
fn foo(a: &Animal, b: &Animal) {
|
||||
match (a, b) {
|
||||
(&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (), // lifetime mismatch error if there is no '&ref'
|
||||
// ^ and ^ should *not* be linted
|
||||
(&Animal::Dog(ref a), &Animal::Dog(_)) => (), // ^ should *not* be linted
|
||||
// ^ and ^ should **not** be linted
|
||||
(&Animal::Dog(ref a), &Animal::Dog(_)) => (), // ^ should **not** be linted
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,6 @@ fn main() {
|
|||
|
||||
let ref mut z = 1 + 2;
|
||||
|
||||
let (ref x, _) = (1, 2); // okay, not top level
|
||||
let (ref x, _) = (1, 2); // ok, not top level
|
||||
println!("The answer is {}.", x);
|
||||
}
|
||||
|
|
|
@ -7,13 +7,13 @@ fn zero() {
|
|||
#[warn(clippy::unicode_not_nfc)]
|
||||
fn canon() {
|
||||
print!("̀àh?");
|
||||
print!("a\u{0300}h?"); // also okay
|
||||
print!("a\u{0300}h?"); // also ok
|
||||
}
|
||||
|
||||
#[warn(clippy::non_ascii_literal)]
|
||||
fn uni() {
|
||||
print!("Üben!");
|
||||
print!("\u{DC}ben!"); // this is okay
|
||||
print!("\u{DC}ben!"); // this is ok
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -9,12 +9,12 @@ macro_rules! test_macro {
|
|||
}};
|
||||
}
|
||||
|
||||
/// Test that we lint if we use a binding with a single leading underscore
|
||||
/// Tests that we lint if we use a binding with a single leading underscore
|
||||
fn prefix_underscore(_foo: u32) -> u32 {
|
||||
_foo + 1
|
||||
}
|
||||
|
||||
/// Test that we lint if we use a `_`-variable defined outside within a macro expansion
|
||||
/// Tests that we lint if we use a `_`-variable defined outside within a macro expansion
|
||||
fn in_macro(_foo: u32) {
|
||||
println!("{}", _foo);
|
||||
assert_eq!(_foo, _foo);
|
||||
|
@ -27,23 +27,23 @@ struct StructFieldTest {
|
|||
_underscore_field: u32,
|
||||
}
|
||||
|
||||
/// Test that we lint the use of a struct field which is prefixed with an underscore
|
||||
/// Tests that we lint the use of a struct field which is prefixed with an underscore
|
||||
fn in_struct_field() {
|
||||
let mut s = StructFieldTest { _underscore_field: 0 };
|
||||
s._underscore_field += 1;
|
||||
}
|
||||
|
||||
/// Test that we do not lint if the underscore is not a prefix
|
||||
/// Tests that we do not lint if the underscore is not a prefix
|
||||
fn non_prefix_underscore(some_foo: u32) -> u32 {
|
||||
some_foo + 1
|
||||
}
|
||||
|
||||
/// Test that we do not lint if we do not use the binding (simple case)
|
||||
/// Tests that we do not lint if we do not use the binding (simple case)
|
||||
fn unused_underscore_simple(_foo: u32) -> u32 {
|
||||
1
|
||||
}
|
||||
|
||||
/// Test that we do not lint if we do not use the binding (complex case). This checks for
|
||||
/// Tests that we do not lint if we do not use the binding (complex case). This checks for
|
||||
/// compatibility with the built-in `unused_variables` lint.
|
||||
fn unused_underscore_complex(mut _foo: u32) -> u32 {
|
||||
_foo += 1;
|
||||
|
@ -64,7 +64,7 @@ enum _EnumTest {
|
|||
_Value(_StructTest),
|
||||
}
|
||||
|
||||
/// Test that we do not lint for non-variable bindings
|
||||
/// Tests that we do not lint for non-variable bindings
|
||||
fn non_variables() {
|
||||
_fn_test();
|
||||
let _s = _StructTest;
|
||||
|
|
|
@ -118,7 +118,7 @@ fn main() {
|
|||
|
||||
// regression test (#360)
|
||||
// this should not panic
|
||||
// it's okay if further iterations of the lint
|
||||
// it's ok if further iterations of the lint
|
||||
// cause this function to trigger it
|
||||
fn no_panic<T>(slice: &[T]) {
|
||||
let mut iter = slice.iter();
|
||||
|
|
Loading…
Reference in a new issue