implement lint double_negations
This commit is contained in:
parent
9e316f3472
commit
c1dcbebd0b
8 changed files with 159 additions and 16 deletions
|
@ -49,16 +49,16 @@ use rustc_trait_selection::traits::{self};
|
|||
use crate::errors::BuiltinEllipsisInclusiveRangePatterns;
|
||||
use crate::lints::{
|
||||
BuiltinAnonymousParams, BuiltinConstNoMangle, BuiltinDeprecatedAttrLink,
|
||||
BuiltinDeprecatedAttrLinkSuggestion, BuiltinDerefNullptr,
|
||||
BuiltinEllipsisInclusiveRangePatternsLint, BuiltinExplicitOutlives,
|
||||
BuiltinExplicitOutlivesSuggestion, BuiltinFeatureIssueNote, BuiltinIncompleteFeatures,
|
||||
BuiltinIncompleteFeaturesHelp, BuiltinInternalFeatures, BuiltinKeywordIdents,
|
||||
BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc, BuiltinMutablesTransmutes,
|
||||
BuiltinNoMangleGeneric, BuiltinNonShorthandFieldPatterns, BuiltinSpecialModuleNameUsed,
|
||||
BuiltinTrivialBounds, BuiltinTypeAliasBounds, BuiltinUngatedAsyncFnTrackCaller,
|
||||
BuiltinUnpermittedTypeInit, BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub,
|
||||
BuiltinUnsafe, BuiltinUnstableFeatures, BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub,
|
||||
BuiltinWhileTrue, InvalidAsmLabel,
|
||||
BuiltinDeprecatedAttrLinkSuggestion, BuiltinDerefNullptr, BuiltinDoubleNegations,
|
||||
BuiltinDoubleNegationsAddParens, BuiltinEllipsisInclusiveRangePatternsLint,
|
||||
BuiltinExplicitOutlives, BuiltinExplicitOutlivesSuggestion, BuiltinFeatureIssueNote,
|
||||
BuiltinIncompleteFeatures, BuiltinIncompleteFeaturesHelp, BuiltinInternalFeatures,
|
||||
BuiltinKeywordIdents, BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc,
|
||||
BuiltinMutablesTransmutes, BuiltinNoMangleGeneric, BuiltinNonShorthandFieldPatterns,
|
||||
BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinTypeAliasBounds,
|
||||
BuiltinUngatedAsyncFnTrackCaller, BuiltinUnpermittedTypeInit, BuiltinUnpermittedTypeInitSub,
|
||||
BuiltinUnreachablePub, BuiltinUnsafe, BuiltinUnstableFeatures, BuiltinUnusedDocComment,
|
||||
BuiltinUnusedDocCommentSub, BuiltinWhileTrue, InvalidAsmLabel,
|
||||
};
|
||||
use crate::nonstandard_style::{MethodLateContext, method_context};
|
||||
use crate::{
|
||||
|
@ -1568,6 +1568,58 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
|
|||
}
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
/// The `double_negations` lint detects expressions of the form `--x`.
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust
|
||||
/// fn main() {
|
||||
/// let x = 1;
|
||||
/// let _b = --x;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// {{produces}}
|
||||
///
|
||||
/// ### Explanation
|
||||
///
|
||||
/// Negating something twice is usually the same as not negating it at all.
|
||||
/// However, a double negation in Rust can easily be confused with the
|
||||
/// prefix decrement operator that exists in many languages derived from C.
|
||||
/// Use `-(-x)` if you really wanted to negate the value twice.
|
||||
///
|
||||
/// To decrement a value, use `x -= 1` instead.
|
||||
pub DOUBLE_NEGATIONS,
|
||||
Warn,
|
||||
"detects expressions of the form `--x`"
|
||||
}
|
||||
|
||||
declare_lint_pass!(
|
||||
/// Lint for expressions of the form `--x` that can be confused with C's
|
||||
/// prefix decrement operator.
|
||||
DoubleNegations => [DOUBLE_NEGATIONS]
|
||||
);
|
||||
|
||||
impl EarlyLintPass for DoubleNegations {
|
||||
#[inline]
|
||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
|
||||
// only lint on the innermost `--` in a chain of `-` operators,
|
||||
// even if there are 3 or more negations
|
||||
if let ExprKind::Unary(UnOp::Neg, ref inner) = expr.kind
|
||||
&& let ExprKind::Unary(UnOp::Neg, ref inner2) = inner.kind
|
||||
&& !matches!(inner2.kind, ExprKind::Unary(UnOp::Neg, _))
|
||||
{
|
||||
cx.emit_span_lint(DOUBLE_NEGATIONS, expr.span, BuiltinDoubleNegations {
|
||||
add_parens: BuiltinDoubleNegationsAddParens {
|
||||
start_span: inner.span.shrink_to_lo(),
|
||||
end_span: inner.span.shrink_to_hi(),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint_pass!(
|
||||
/// Does nothing as a lint pass, but registers some `Lint`s
|
||||
/// which are used by other parts of the compiler.
|
||||
|
@ -1586,7 +1638,8 @@ declare_lint_pass!(
|
|||
UNSTABLE_FEATURES,
|
||||
UNREACHABLE_PUB,
|
||||
TYPE_ALIAS_BOUNDS,
|
||||
TRIVIAL_BOUNDS
|
||||
TRIVIAL_BOUNDS,
|
||||
DOUBLE_NEGATIONS
|
||||
]
|
||||
);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue