Skip to content

Commit d918cd9

Browse files
committed
submodules: update clippy from af5940b to 6651c1b
Changes: ```` Rename dummy_hir_id -> parent_hir_id rustup rust-lang/rust#71116 Change default many single char names threshold Better precedence case management + more tests Use only check_expr with parent expr and precedence Check for Deref trait impl + add fixed version Report using stmts and expr + tests Global rework + fix imports Working basic dereference clip Add test for zero single char names Make the single char threshold strict inequality large_enum_variant: Report sizes of variants Refactor: Use rustc's `match_def_path` deps: bump compiletest-rs from 0.4 to 0.5 rustup rust-lang/rust#70643 Explain panic on `E0463` in integration tests Temporarily disable rustfmt integration test result_map_unit_fn: Fix incorrect UI tests Cleanup: Use rustc's is_proc_macro_attr Cleanup: Use our `sym!` macro more Fixes rust-lang#5405: redundant clone false positive with arrays Disallow bit-shifting in `integer_arithmetic` lint update lints cargo dev fmt Make use of Option/Result diagnostic items Make use of some existing diagnostic items Say that diagnostic items are preferred over paths verbose_bit_mask: fix bit mask used in docs Update documentation for new_ret_no_self Update doc generation script Add lint on large const arrays Make the epsilon note spanless Split check_fn function Indicate when arrays are compared in error message Make epsilon note spanless when comparing arrays Add float cmp const tests for arrays Add float cmp tests for arrays Handle constant arrays with single value Don't show comparison suggestion for arrays Allow for const arrays of zeros Handle evaluating constant index expression Add handling of float arrays to miri_to_const Update stderr of float_cmp test Update field names in is_float Add tests for float in array comparison Add lint when comparing floats in an array ```` Fixes #71114
1 parent 1c52c27 commit d918cd9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+1150
-250
lines changed

.github/workflows/clippy_bors.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,8 @@ jobs:
234234
- 'rust-lang/cargo'
235235
- 'rust-lang/rls'
236236
- 'rust-lang/chalk'
237-
- 'rust-lang/rustfmt'
237+
# FIXME: Disabled until https://github.com/rust-lang/rust/issues/71077 is fixed
238+
# - 'rust-lang/rustfmt'
238239
- 'Marwes/combine'
239240
- 'Geal/nom'
240241
- 'rust-lang/stdarch'

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,7 @@ Released 2018-09-13
12561256
[`expect_fun_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#expect_fun_call
12571257
[`expl_impl_clone_on_copy`]: https://rust-lang.github.io/rust-clippy/master/index.html#expl_impl_clone_on_copy
12581258
[`explicit_counter_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_counter_loop
1259+
[`explicit_deref_methods`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_deref_methods
12591260
[`explicit_into_iter_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_into_iter_loop
12601261
[`explicit_iter_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_iter_loop
12611262
[`explicit_write`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_write
@@ -1319,6 +1320,7 @@ Released 2018-09-13
13191320
[`iter_skip_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_skip_next
13201321
[`iterator_step_by_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#iterator_step_by_zero
13211322
[`just_underscores_and_digits`]: https://rust-lang.github.io/rust-clippy/master/index.html#just_underscores_and_digits
1323+
[`large_const_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_const_arrays
13221324
[`large_digit_groups`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_digit_groups
13231325
[`large_enum_variant`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant
13241326
[`large_stack_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ lazy_static = "1.0"
4242

4343
[dev-dependencies]
4444
cargo_metadata = "0.9.0"
45-
compiletest_rs = { version = "0.4.0", features = ["tmp"] }
45+
compiletest_rs = { version = "0.5.0", features = ["tmp"] }
4646
tester = "0.7"
4747
lazy_static = "1.0"
4848
clippy-mini-macro-test = { version = "0.2", path = "mini-macro" }

clippy_lints/src/arithmetic.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,17 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
66
use rustc_span::source_map::Span;
77

88
declare_clippy_lint! {
9-
/// **What it does:** Checks for plain integer arithmetic.
9+
/// **What it does:** Checks for integer arithmetic operations which could overflow or panic.
1010
///
11-
/// **Why is this bad?** This is only checked against overflow in debug builds.
12-
/// In some applications one wants explicitly checked, wrapping or saturating
13-
/// arithmetic.
11+
/// Specifically, checks for any operators (`+`, `-`, `*`, `<<`, etc) which are capable
12+
/// of overflowing according to the [Rust
13+
/// Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow),
14+
/// or which can panic (`/`, `%`). No bounds analysis or sophisticated reasoning is
15+
/// attempted.
16+
///
17+
/// **Why is this bad?** Integer overflow will trigger a panic in debug builds or will wrap in
18+
/// release mode. Division by zero will cause a panic in either mode. In some applications one
19+
/// wants explicitly checked, wrapping or saturating arithmetic.
1420
///
1521
/// **Known problems:** None.
1622
///
@@ -21,7 +27,7 @@ declare_clippy_lint! {
2127
/// ```
2228
pub INTEGER_ARITHMETIC,
2329
restriction,
24-
"any integer arithmetic statement"
30+
"any integer arithmetic expression which could overflow or panic"
2531
}
2632

2733
declare_clippy_lint! {
@@ -71,8 +77,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Arithmetic {
7177
| hir::BinOpKind::BitAnd
7278
| hir::BinOpKind::BitOr
7379
| hir::BinOpKind::BitXor
74-
| hir::BinOpKind::Shl
75-
| hir::BinOpKind::Shr
7680
| hir::BinOpKind::Eq
7781
| hir::BinOpKind::Lt
7882
| hir::BinOpKind::Le

clippy_lints/src/bit_mask.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ declare_clippy_lint! {
8787
/// **Example:**
8888
/// ```rust
8989
/// # let x = 1;
90-
/// if x & 0x1111 == 0 { }
90+
/// if x & 0b1111 == 0 { }
9191
/// ```
9292
pub VERBOSE_BIT_MASK,
9393
style,

clippy_lints/src/booleans.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::utils::{
2-
get_trait_def_id, implements_trait, in_macro, match_type, paths, snippet_opt, span_lint_and_sugg,
2+
get_trait_def_id, implements_trait, in_macro, is_type_diagnostic_item, paths, snippet_opt, span_lint_and_sugg,
33
span_lint_and_then, SpanlessEq,
44
};
55
use if_chain::if_chain;
@@ -249,7 +249,9 @@ fn simplify_not(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option<String> {
249249
},
250250
ExprKind::MethodCall(path, _, args) if args.len() == 1 => {
251251
let type_of_receiver = cx.tables.expr_ty(&args[0]);
252-
if !match_type(cx, type_of_receiver, &paths::OPTION) && !match_type(cx, type_of_receiver, &paths::RESULT) {
252+
if !is_type_diagnostic_item(cx, type_of_receiver, sym!(option_type))
253+
&& !is_type_diagnostic_item(cx, type_of_receiver, sym!(result_type))
254+
{
253255
return None;
254256
}
255257
METHODS_WITH_NEGATION

clippy_lints/src/cognitive_complexity.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
99
use rustc_span::source_map::Span;
1010
use rustc_span::BytePos;
1111

12-
use crate::utils::{match_type, paths, snippet_opt, span_lint_and_help, LimitStack};
12+
use crate::utils::{is_type_diagnostic_item, snippet_opt, span_lint_and_help, LimitStack};
1313

1414
declare_clippy_lint! {
1515
/// **What it does:** Checks for methods with high cognitive complexity.
@@ -61,7 +61,7 @@ impl CognitiveComplexity {
6161
helper.visit_expr(expr);
6262
let CCHelper { cc, returns } = helper;
6363
let ret_ty = cx.tables.node_type(expr.hir_id);
64-
let ret_adjust = if match_type(cx, ret_ty, &paths::RESULT) {
64+
let ret_adjust = if is_type_diagnostic_item(cx, ret_ty, sym!(result_type)) {
6565
returns
6666
} else {
6767
#[allow(clippy::integer_division)]

clippy_lints/src/consts.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
268268
}
269269
}
270270
},
271+
ExprKind::Index(ref arr, ref index) => self.index(arr, index),
271272
// TODO: add other expressions.
272273
_ => None,
273274
}
@@ -345,6 +346,31 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
345346
}
346347
}
347348

349+
fn index(&mut self, lhs: &'_ Expr<'_>, index: &'_ Expr<'_>) -> Option<Constant> {
350+
let lhs = self.expr(lhs);
351+
let index = self.expr(index);
352+
353+
match (lhs, index) {
354+
(Some(Constant::Vec(vec)), Some(Constant::Int(index))) => match vec[index as usize] {
355+
Constant::F32(x) => Some(Constant::F32(x)),
356+
Constant::F64(x) => Some(Constant::F64(x)),
357+
_ => None,
358+
},
359+
(Some(Constant::Vec(vec)), _) => {
360+
if !vec.is_empty() && vec.iter().all(|x| *x == vec[0]) {
361+
match vec[0] {
362+
Constant::F32(x) => Some(Constant::F32(x)),
363+
Constant::F64(x) => Some(Constant::F64(x)),
364+
_ => None,
365+
}
366+
} else {
367+
None
368+
}
369+
},
370+
_ => None,
371+
}
372+
}
373+
348374
/// A block can only yield a constant if it only has one constant expression.
349375
fn block(&mut self, block: &Block<'_>) -> Option<Constant> {
350376
if block.stmts.is_empty() {
@@ -492,6 +518,41 @@ pub fn miri_to_const(result: &ty::Const<'_>) -> Option<Constant> {
492518
},
493519
_ => None,
494520
},
521+
ty::ConstKind::Value(ConstValue::ByRef { alloc, offset: _ }) => match result.ty.kind {
522+
ty::Array(sub_type, len) => match sub_type.kind {
523+
ty::Float(FloatTy::F32) => match miri_to_const(len) {
524+
Some(Constant::Int(len)) => alloc
525+
.inspect_with_undef_and_ptr_outside_interpreter(0..(4 * len as usize))
526+
.to_owned()
527+
.chunks(4)
528+
.map(|chunk| {
529+
Some(Constant::F32(f32::from_le_bytes(
530+
chunk.try_into().expect("this shouldn't happen"),
531+
)))
532+
})
533+
.collect::<Option<Vec<Constant>>>()
534+
.map(Constant::Vec),
535+
_ => None,
536+
},
537+
ty::Float(FloatTy::F64) => match miri_to_const(len) {
538+
Some(Constant::Int(len)) => alloc
539+
.inspect_with_undef_and_ptr_outside_interpreter(0..(8 * len as usize))
540+
.to_owned()
541+
.chunks(8)
542+
.map(|chunk| {
543+
Some(Constant::F64(f64::from_le_bytes(
544+
chunk.try_into().expect("this shouldn't happen"),
545+
)))
546+
})
547+
.collect::<Option<Vec<Constant>>>()
548+
.map(Constant::Vec),
549+
_ => None,
550+
},
551+
// FIXME: implement other array type conversions.
552+
_ => None,
553+
},
554+
_ => None,
555+
},
495556
// FIXME: implement other conversions.
496557
_ => None,
497558
}

clippy_lints/src/dereference.rs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
use crate::utils::{get_parent_expr, implements_trait, snippet, span_lint_and_sugg};
2+
use if_chain::if_chain;
3+
use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX, PREC_PREFIX};
4+
use rustc_errors::Applicability;
5+
use rustc_hir::{Expr, ExprKind};
6+
use rustc_lint::{LateContext, LateLintPass};
7+
use rustc_session::{declare_lint_pass, declare_tool_lint};
8+
use rustc_span::source_map::Span;
9+
10+
declare_clippy_lint! {
11+
/// **What it does:** Checks for explicit `deref()` or `deref_mut()` method calls.
12+
///
13+
/// **Why is this bad?** Derefencing by `&*x` or `&mut *x` is clearer and more concise,
14+
/// when not part of a method chain.
15+
///
16+
/// **Example:**
17+
/// ```rust
18+
/// use std::ops::Deref;
19+
/// let a: &mut String = &mut String::from("foo");
20+
/// let b: &str = a.deref();
21+
/// ```
22+
/// Could be written as:
23+
/// ```rust
24+
/// let a: &mut String = &mut String::from("foo");
25+
/// let b = &*a;
26+
/// ```
27+
///
28+
/// This lint excludes
29+
/// ```rust,ignore
30+
/// let _ = d.unwrap().deref();
31+
/// ```
32+
pub EXPLICIT_DEREF_METHODS,
33+
pedantic,
34+
"Explicit use of deref or deref_mut method while not in a method chain."
35+
}
36+
37+
declare_lint_pass!(Dereferencing => [
38+
EXPLICIT_DEREF_METHODS
39+
]);
40+
41+
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Dereferencing {
42+
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) {
43+
if_chain! {
44+
if !expr.span.from_expansion();
45+
if let ExprKind::MethodCall(ref method_name, _, ref args) = &expr.kind;
46+
if args.len() == 1;
47+
48+
then {
49+
if let Some(parent_expr) = get_parent_expr(cx, expr) {
50+
// Check if we have the whole call chain here
51+
if let ExprKind::MethodCall(..) = parent_expr.kind {
52+
return;
53+
}
54+
// Check for Expr that we don't want to be linted
55+
let precedence = parent_expr.precedence();
56+
match precedence {
57+
// Lint a Call is ok though
58+
ExprPrecedence::Call | ExprPrecedence::AddrOf => (),
59+
_ => {
60+
if precedence.order() >= PREC_PREFIX && precedence.order() <= PREC_POSTFIX {
61+
return;
62+
}
63+
}
64+
}
65+
}
66+
let name = method_name.ident.as_str();
67+
lint_deref(cx, &*name, &args[0], args[0].span, expr.span);
68+
}
69+
}
70+
}
71+
}
72+
73+
fn lint_deref(cx: &LateContext<'_, '_>, method_name: &str, call_expr: &Expr<'_>, var_span: Span, expr_span: Span) {
74+
match method_name {
75+
"deref" => {
76+
if cx
77+
.tcx
78+
.lang_items()
79+
.deref_trait()
80+
.map_or(false, |id| implements_trait(cx, cx.tables.expr_ty(&call_expr), id, &[]))
81+
{
82+
span_lint_and_sugg(
83+
cx,
84+
EXPLICIT_DEREF_METHODS,
85+
expr_span,
86+
"explicit deref method call",
87+
"try this",
88+
format!("&*{}", &snippet(cx, var_span, "..")),
89+
Applicability::MachineApplicable,
90+
);
91+
}
92+
},
93+
"deref_mut" => {
94+
if cx
95+
.tcx
96+
.lang_items()
97+
.deref_mut_trait()
98+
.map_or(false, |id| implements_trait(cx, cx.tables.expr_ty(&call_expr), id, &[]))
99+
{
100+
span_lint_and_sugg(
101+
cx,
102+
EXPLICIT_DEREF_METHODS,
103+
expr_span,
104+
"explicit deref_mut method call",
105+
"try this",
106+
format!("&mut *{}", &snippet(cx, var_span, "..")),
107+
Applicability::MachineApplicable,
108+
);
109+
}
110+
},
111+
_ => (),
112+
}
113+
}

clippy_lints/src/doc.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::utils::{implements_trait, is_entrypoint_fn, match_type, paths, return_ty, span_lint};
1+
use crate::utils::{implements_trait, is_entrypoint_fn, is_type_diagnostic_item, return_ty, span_lint};
22
use if_chain::if_chain;
33
use itertools::Itertools;
44
use rustc_ast::ast::{AttrKind, Attribute};
@@ -217,7 +217,7 @@ fn lint_for_missing_headers<'a, 'tcx>(
217217
);
218218
}
219219
if !headers.errors {
220-
if match_type(cx, return_ty(cx, hir_id), &paths::RESULT) {
220+
if is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym!(result_type)) {
221221
span_lint(
222222
cx,
223223
MISSING_ERRORS_DOC,
@@ -235,7 +235,7 @@ fn lint_for_missing_headers<'a, 'tcx>(
235235
if let ty::Opaque(_, subs) = ret_ty.kind;
236236
if let Some(gen) = subs.types().next();
237237
if let ty::Generator(_, subs, _) = gen.kind;
238-
if match_type(cx, subs.as_generator().return_ty(), &paths::RESULT);
238+
if is_type_diagnostic_item(cx, subs.as_generator().return_ty(), sym!(result_type));
239239
then {
240240
span_lint(
241241
cx,

clippy_lints/src/fallible_impl_from.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
use crate::utils::paths::{BEGIN_PANIC, BEGIN_PANIC_FMT, FROM_TRAIT, OPTION, RESULT};
2-
use crate::utils::{is_expn_of, match_def_path, method_chain_args, span_lint_and_then, walk_ptrs_ty};
1+
use crate::utils::paths::{BEGIN_PANIC, BEGIN_PANIC_FMT, FROM_TRAIT};
2+
use crate::utils::{
3+
is_expn_of, is_type_diagnostic_item, match_def_path, method_chain_args, span_lint_and_then, walk_ptrs_ty,
4+
};
35
use if_chain::if_chain;
46
use rustc_hir as hir;
57
use rustc_lint::{LateContext, LateLintPass};
68
use rustc_middle::hir::map::Map;
7-
use rustc_middle::ty::{self, Ty};
9+
use rustc_middle::ty;
810
use rustc_session::{declare_lint_pass, declare_tool_lint};
911
use rustc_span::Span;
1012

@@ -76,7 +78,9 @@ fn lint_impl_body<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, impl_span: Span, impl_it
7678
// check for `unwrap`
7779
if let Some(arglists) = method_chain_args(expr, &["unwrap"]) {
7880
let reciever_ty = walk_ptrs_ty(self.tables.expr_ty(&arglists[0][0]));
79-
if match_type(self.lcx, reciever_ty, &OPTION) || match_type(self.lcx, reciever_ty, &RESULT) {
81+
if is_type_diagnostic_item(self.lcx, reciever_ty, sym!(option_type))
82+
|| is_type_diagnostic_item(self.lcx, reciever_ty, sym!(result_type))
83+
{
8084
self.result.push(expr.span);
8185
}
8286
}
@@ -124,10 +128,3 @@ fn lint_impl_body<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, impl_span: Span, impl_it
124128
}
125129
}
126130
}
127-
128-
fn match_type(cx: &LateContext<'_, '_>, ty: Ty<'_>, path: &[&str]) -> bool {
129-
match ty.kind {
130-
ty::Adt(adt, _) => match_def_path(cx, adt.did, path),
131-
_ => false,
132-
}
133-
}

0 commit comments

Comments
 (0)