Skip to content

Commit b452ad3

Browse files
committed
Auto merge of #5741 - flip1995:rollup-8chbwhy, r=flip1995
Rollup of 9 pull requests Successful merges: - #5178 (clippy-driver: pass all args to rustc if --rustc is present) - #5705 (Downgrade unnested_or_patterns to pedantic) - #5709 (Fix ICE in consts::binop) - #5710 (typo) - #5712 (Remove `bar` from blacklisted names) - #5713 (Use lints in Clippy that are enabled in rustc bootstrap) - #5716 (Fix typo in wildcard_imports) - #5724 (redundant_pattern_matching: avoid non-`const fn` calls in const contexts) - #5726 (Fix typo) Failed merges: r? @ghost changelog: rollup
2 parents 4cc2fa9 + e4cbd1d commit b452ad3

25 files changed

+454
-125
lines changed

.github/driver.sh

+12
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,16 @@ unset CARGO_MANIFEST_DIR
2626
sed -e "s,tests/ui,\$DIR," -e "/= help/d" cstring.stderr > normalized.stderr
2727
diff normalized.stderr tests/ui/cstring.stderr
2828

29+
30+
# make sure "clippy-driver --rustc --arg" and "rustc --arg" behave the same
31+
SYSROOT=`rustc --print sysroot`
32+
diff <(LD_LIBRARY_PATH=${SYSROOT}/lib ./target/debug/clippy-driver --rustc --version --verbose) <(rustc --version --verbose)
33+
34+
35+
echo "fn main() {}" > target/driver_test.rs
36+
# we can't run 2 rustcs on the same file at the same time
37+
CLIPPY=`LD_LIBRARY_PATH=${SYSROOT}/lib ./target/debug/clippy-driver ./target/driver_test.rs --rustc`
38+
RUSTC=`rustc ./target/driver_test.rs`
39+
diff <($CLIPPY) <($RUSTC)
40+
2941
# TODO: CLIPPY_CONF_DIR / CARGO_MANIFEST_DIR

clippy_lints/src/consts.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
396396
let l = self.expr(left)?;
397397
let r = self.expr(right);
398398
match (l, r) {
399-
(Constant::Int(l), Some(Constant::Int(r))) => match self.tables.expr_ty(left).kind {
399+
(Constant::Int(l), Some(Constant::Int(r))) => match self.tables.expr_ty_opt(left)?.kind {
400400
ty::Int(ity) => {
401401
let l = sext(self.lcx.tcx, l, ity);
402402
let r = sext(self.lcx.tcx, r, ity);

clippy_lints/src/let_underscore.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ declare_clippy_lint! {
3535
/// **What it does:** Checks for `let _ = sync_lock`
3636
///
3737
/// **Why is this bad?** This statement immediately drops the lock instead of
38-
/// extending it's lifetime to the end of the scope, which is often not intended.
38+
/// extending its lifetime to the end of the scope, which is often not intended.
3939
/// To extend lock lifetime to the end of the scope, use an underscore-prefixed
4040
/// name instead (i.e. _lock). If you want to explicitly drop the lock,
4141
/// `std::mem::drop` conveys your intention better and is less error-prone.

clippy_lints/src/lib.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
// error-pattern:cargo-clippy
22

33
#![feature(bindings_after_at)]
4-
#![feature(box_syntax)]
54
#![feature(box_patterns)]
5+
#![feature(box_syntax)]
6+
#![feature(concat_idents)]
7+
#![feature(crate_visibility_modifier)]
8+
#![feature(drain_filter)]
69
#![feature(or_patterns)]
710
#![feature(rustc_private)]
811
#![feature(stmt_expr_attributes)]
9-
#![allow(clippy::missing_docs_in_private_items, clippy::must_use_candidate)]
1012
#![recursion_limit = "512"]
11-
#![warn(rust_2018_idioms, trivial_casts, trivial_numeric_casts)]
12-
#![deny(rustc::internal)]
1313
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
14-
#![feature(crate_visibility_modifier)]
15-
#![feature(concat_idents)]
16-
#![feature(drain_filter)]
14+
#![allow(clippy::missing_docs_in_private_items, clippy::must_use_candidate)]
15+
#![warn(trivial_casts, trivial_numeric_casts)]
16+
// warn on lints, that are included in `rust-lang/rust`s bootstrap
17+
#![warn(rust_2018_idioms, unused_lifetimes)]
18+
// warn on rustc internal lints
19+
#![deny(rustc::internal)]
1720

1821
// FIXME: switch to something more ergonomic here, once available.
1922
// (Currently there is no way to opt into sysroot crates without `extern crate`.)
@@ -1187,6 +1190,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
11871190
LintId::of(&types::OPTION_OPTION),
11881191
LintId::of(&unicode::NON_ASCII_LITERAL),
11891192
LintId::of(&unicode::UNICODE_NOT_NFC),
1193+
LintId::of(&unnested_or_patterns::UNNESTED_OR_PATTERNS),
11901194
LintId::of(&unused_self::UNUSED_SELF),
11911195
LintId::of(&wildcard_imports::ENUM_GLOB_USE),
11921196
LintId::of(&wildcard_imports::WILDCARD_IMPORTS),
@@ -1440,7 +1444,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
14401444
LintId::of(&unnamed_address::FN_ADDRESS_COMPARISONS),
14411445
LintId::of(&unnamed_address::VTABLE_ADDRESS_COMPARISONS),
14421446
LintId::of(&unnecessary_sort_by::UNNECESSARY_SORT_BY),
1443-
LintId::of(&unnested_or_patterns::UNNESTED_OR_PATTERNS),
14441447
LintId::of(&unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME),
14451448
LintId::of(&unused_io_amount::UNUSED_IO_AMOUNT),
14461449
LintId::of(&unwrap::PANICKING_UNWRAP),
@@ -1624,7 +1627,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
16241627
LintId::of(&types::UNNECESSARY_CAST),
16251628
LintId::of(&types::VEC_BOX),
16261629
LintId::of(&unnecessary_sort_by::UNNECESSARY_SORT_BY),
1627-
LintId::of(&unnested_or_patterns::UNNESTED_OR_PATTERNS),
16281630
LintId::of(&unwrap::UNNECESSARY_UNWRAP),
16291631
LintId::of(&useless_conversion::USELESS_CONVERSION),
16301632
LintId::of(&zero_div_zero::ZERO_DIVIDED_BY_ZERO),

clippy_lints/src/loops.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1497,7 +1497,7 @@ struct MutatePairDelegate<'a, 'tcx> {
14971497
span_high: Option<Span>,
14981498
}
14991499

1500-
impl<'a, 'tcx> Delegate<'tcx> for MutatePairDelegate<'a, 'tcx> {
1500+
impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> {
15011501
fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: ConsumeMode) {}
15021502

15031503
fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, bk: ty::BorrowKind) {
@@ -1525,7 +1525,7 @@ impl<'a, 'tcx> Delegate<'tcx> for MutatePairDelegate<'a, 'tcx> {
15251525
}
15261526
}
15271527

1528-
impl<'a, 'tcx> MutatePairDelegate<'a, 'tcx> {
1528+
impl MutatePairDelegate<'_, '_> {
15291529
fn mutation_span(&self) -> (Option<Span>, Option<Span>) {
15301530
(self.span_low, self.span_high)
15311531
}
@@ -2292,7 +2292,7 @@ struct HasBreakOrReturnVisitor {
22922292
has_break_or_return: bool,
22932293
}
22942294

2295-
impl<'a, 'tcx> Visitor<'tcx> for HasBreakOrReturnVisitor {
2295+
impl<'tcx> Visitor<'tcx> for HasBreakOrReturnVisitor {
22962296
type Map = Map<'tcx>;
22972297

22982298
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {

clippy_lints/src/new_without_default.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ declare_clippy_lint! {
3333
/// }
3434
/// ```
3535
///
36-
/// To fix the lint, and a `Default` implementation that delegates to `new`:
36+
/// To fix the lint, add a `Default` implementation that delegates to `new`:
3737
///
3838
/// ```ignore
3939
/// struct Foo(Bar);

clippy_lints/src/redundant_pattern_matching.rs

+62-18
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
use crate::utils::{match_qpath, match_trait_method, paths, snippet, span_lint_and_then};
1+
use crate::utils::{in_constant, match_qpath, match_trait_method, paths, snippet, span_lint_and_then};
22
use if_chain::if_chain;
33
use rustc_ast::ast::LitKind;
44
use rustc_errors::Applicability;
5-
use rustc_hir::{Arm, Expr, ExprKind, MatchSource, PatKind, QPath};
5+
use rustc_hir::{Arm, Expr, ExprKind, HirId, MatchSource, PatKind, QPath};
66
use rustc_lint::{LateContext, LateLintPass};
7+
use rustc_middle::ty;
8+
use rustc_mir::const_eval::is_const_fn;
79
use rustc_session::{declare_lint_pass, declare_tool_lint};
10+
use rustc_span::source_map::Symbol;
811

912
declare_clippy_lint! {
1013
/// **What it does:** Lint for redundant pattern matching over `Result` or
@@ -64,26 +67,37 @@ fn find_sugg_for_if_let<'a, 'tcx>(
6467
arms: &[Arm<'_>],
6568
keyword: &'static str,
6669
) {
70+
fn find_suggestion(cx: &LateContext<'_, '_>, hir_id: HirId, path: &QPath<'_>) -> Option<&'static str> {
71+
if match_qpath(path, &paths::RESULT_OK) && can_suggest(cx, hir_id, sym!(result_type), "is_ok") {
72+
return Some("is_ok()");
73+
}
74+
if match_qpath(path, &paths::RESULT_ERR) && can_suggest(cx, hir_id, sym!(result_type), "is_err") {
75+
return Some("is_err()");
76+
}
77+
if match_qpath(path, &paths::OPTION_SOME) && can_suggest(cx, hir_id, sym!(option_type), "is_some") {
78+
return Some("is_some()");
79+
}
80+
if match_qpath(path, &paths::OPTION_NONE) && can_suggest(cx, hir_id, sym!(option_type), "is_none") {
81+
return Some("is_none()");
82+
}
83+
None
84+
}
85+
86+
let hir_id = expr.hir_id;
6787
let good_method = match arms[0].pat.kind {
6888
PatKind::TupleStruct(ref path, ref patterns, _) if patterns.len() == 1 => {
6989
if let PatKind::Wild = patterns[0].kind {
70-
if match_qpath(path, &paths::RESULT_OK) {
71-
"is_ok()"
72-
} else if match_qpath(path, &paths::RESULT_ERR) {
73-
"is_err()"
74-
} else if match_qpath(path, &paths::OPTION_SOME) {
75-
"is_some()"
76-
} else {
77-
return;
78-
}
90+
find_suggestion(cx, hir_id, path)
7991
} else {
80-
return;
92+
None
8193
}
8294
},
83-
84-
PatKind::Path(ref path) if match_qpath(path, &paths::OPTION_NONE) => "is_none()",
85-
86-
_ => return,
95+
PatKind::Path(ref path) => find_suggestion(cx, hir_id, path),
96+
_ => None,
97+
};
98+
let good_method = match good_method {
99+
Some(method) => method,
100+
None => return,
87101
};
88102

89103
// check that `while_let_on_iterator` lint does not trigger
@@ -128,6 +142,7 @@ fn find_sugg_for_match<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_
128142
if arms.len() == 2 {
129143
let node_pair = (&arms[0].pat.kind, &arms[1].pat.kind);
130144

145+
let hir_id = expr.hir_id;
131146
let found_good_method = match node_pair {
132147
(
133148
PatKind::TupleStruct(ref path_left, ref patterns_left, _),
@@ -142,6 +157,8 @@ fn find_sugg_for_match<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_
142157
&paths::RESULT_ERR,
143158
"is_ok()",
144159
"is_err()",
160+
|| can_suggest(cx, hir_id, sym!(result_type), "is_ok"),
161+
|| can_suggest(cx, hir_id, sym!(result_type), "is_err"),
145162
)
146163
} else {
147164
None
@@ -160,6 +177,8 @@ fn find_sugg_for_match<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_
160177
&paths::OPTION_NONE,
161178
"is_some()",
162179
"is_none()",
180+
|| can_suggest(cx, hir_id, sym!(option_type), "is_some"),
181+
|| can_suggest(cx, hir_id, sym!(option_type), "is_none"),
163182
)
164183
} else {
165184
None
@@ -188,6 +207,7 @@ fn find_sugg_for_match<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_
188207
}
189208
}
190209

210+
#[allow(clippy::too_many_arguments)]
191211
fn find_good_method_for_match<'a>(
192212
arms: &[Arm<'_>],
193213
path_left: &QPath<'_>,
@@ -196,6 +216,8 @@ fn find_good_method_for_match<'a>(
196216
expected_right: &[&str],
197217
should_be_left: &'a str,
198218
should_be_right: &'a str,
219+
can_suggest_left: impl Fn() -> bool,
220+
can_suggest_right: impl Fn() -> bool,
199221
) -> Option<&'a str> {
200222
let body_node_pair = if match_qpath(path_left, expected_left) && match_qpath(path_right, expected_right) {
201223
(&(*arms[0].body).kind, &(*arms[1].body).kind)
@@ -207,10 +229,32 @@ fn find_good_method_for_match<'a>(
207229

208230
match body_node_pair {
209231
(ExprKind::Lit(ref lit_left), ExprKind::Lit(ref lit_right)) => match (&lit_left.node, &lit_right.node) {
210-
(LitKind::Bool(true), LitKind::Bool(false)) => Some(should_be_left),
211-
(LitKind::Bool(false), LitKind::Bool(true)) => Some(should_be_right),
232+
(LitKind::Bool(true), LitKind::Bool(false)) if can_suggest_left() => Some(should_be_left),
233+
(LitKind::Bool(false), LitKind::Bool(true)) if can_suggest_right() => Some(should_be_right),
212234
_ => None,
213235
},
214236
_ => None,
215237
}
216238
}
239+
240+
fn can_suggest(cx: &LateContext<'_, '_>, hir_id: HirId, diag_item: Symbol, name: &str) -> bool {
241+
if !in_constant(cx, hir_id) {
242+
return true;
243+
}
244+
245+
// Avoid suggesting calls to non-`const fn`s in const contexts, see #5697.
246+
cx.tcx
247+
.get_diagnostic_item(diag_item)
248+
.and_then(|def_id| {
249+
cx.tcx.inherent_impls(def_id).iter().find_map(|imp| {
250+
cx.tcx
251+
.associated_items(*imp)
252+
.in_definition_order()
253+
.find_map(|item| match item.kind {
254+
ty::AssocKind::Fn if item.ident.name.as_str() == name => Some(item.def_id),
255+
_ => None,
256+
})
257+
})
258+
})
259+
.map_or(false, |def_id| is_const_fn(cx.tcx, def_id))
260+
}

clippy_lints/src/suspicious_trait_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ struct BinaryExprVisitor {
184184
in_binary_expr: bool,
185185
}
186186

187-
impl<'a, 'tcx> Visitor<'tcx> for BinaryExprVisitor {
187+
impl<'tcx> Visitor<'tcx> for BinaryExprVisitor {
188188
type Map = Map<'tcx>;
189189

190190
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'_>) {

clippy_lints/src/trivially_copy_pass_by_ref.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ pub struct TriviallyCopyPassByRef {
5858
limit: u64,
5959
}
6060

61-
impl<'a, 'tcx> TriviallyCopyPassByRef {
61+
impl<'tcx> TriviallyCopyPassByRef {
6262
pub fn new(limit: Option<u64>, target: &SessionConfig) -> Self {
6363
let limit = limit.unwrap_or_else(|| {
6464
let bit_width = u64::from(target.ptr_width);

clippy_lints/src/unnested_or_patterns.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ declare_clippy_lint! {
4545
/// }
4646
/// ```
4747
pub UNNESTED_OR_PATTERNS,
48-
complexity,
48+
pedantic,
4949
"unnested or-patterns, e.g., `Foo(Bar) | Foo(Baz) instead of `Foo(Bar | Baz)`"
5050
}
5151

clippy_lints/src/utils/conf.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ macro_rules! define_Conf {
106106

107107
pub use self::helpers::Conf;
108108
define_Conf! {
109-
/// Lint: BLACKLISTED_NAME. The list of blacklisted names to lint about
110-
(blacklisted_names, "blacklisted_names": Vec<String>, ["foo", "bar", "baz", "quux"].iter().map(ToString::to_string).collect()),
109+
/// Lint: BLACKLISTED_NAME. The list of blacklisted names to lint about. NB: `bar` is not here since it has legitimate uses
110+
(blacklisted_names, "blacklisted_names": Vec<String>, ["foo", "baz", "quux"].iter().map(ToString::to_string).collect()),
111111
/// Lint: COGNITIVE_COMPLEXITY. The maximum cognitive complexity a function can have
112112
(cognitive_complexity_threshold, "cognitive_complexity_threshold": u64, 25),
113113
/// DEPRECATED LINT: CYCLOMATIC_COMPLEXITY. Use the Cognitive Complexity lint instead.

clippy_lints/src/utils/sugg.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ fn indentation<T: LintContext>(cx: &T, span: Span) -> Option<String> {
509509
}
510510

511511
/// Convenience extension trait for `DiagnosticBuilder`.
512-
pub trait DiagnosticBuilderExt<'a, T: LintContext> {
512+
pub trait DiagnosticBuilderExt<T: LintContext> {
513513
/// Suggests to add an attribute to an item.
514514
///
515515
/// Correctly handles indentation of the attribute and item.
@@ -556,7 +556,7 @@ pub trait DiagnosticBuilderExt<'a, T: LintContext> {
556556
fn suggest_remove_item(&mut self, cx: &T, item: Span, msg: &str, applicability: Applicability);
557557
}
558558

559-
impl<'a, 'b, 'c, T: LintContext> DiagnosticBuilderExt<'c, T> for rustc_errors::DiagnosticBuilder<'b> {
559+
impl<T: LintContext> DiagnosticBuilderExt<T> for rustc_errors::DiagnosticBuilder<'_> {
560560
fn suggest_item_with_attr<D: Display + ?Sized>(
561561
&mut self,
562562
cx: &T,

clippy_lints/src/wildcard_imports.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ declare_clippy_lint! {
3636
declare_clippy_lint! {
3737
/// **What it does:** Checks for wildcard imports `use _::*`.
3838
///
39-
/// **Why is this bad?** wildcard imports can polute the namespace. This is especially bad if
39+
/// **Why is this bad?** wildcard imports can pollute the namespace. This is especially bad if
4040
/// you try to import something through a wildcard, that already has been imported by name from
4141
/// a different source:
4242
///

0 commit comments

Comments
 (0)