From 4e4c4fb8aa5010313c8bcc8a6f1edd9912702269 Mon Sep 17 00:00:00 2001 From: Camelid Date: Tue, 17 Nov 2020 12:16:15 -0800 Subject: [PATCH 1/4] Fix handling of panic calls This should make Clippy more resilient and will unblock #78343. This PR is made against rust-lang/rust to avoid the need for a subtree sync at @flip1995's suggestion in rust-lang/rust-clippy#6310. --- clippy_lints/src/assertions_on_constants.rs | 5 +-- clippy_lints/src/attrs.rs | 4 +- clippy_lints/src/fallible_impl_from.rs | 9 ++-- clippy_lints/src/implicit_return.rs | 9 +--- clippy_lints/src/panic_unimplemented.rs | 44 +++++++++--------- clippy_lints/src/utils/mod.rs | 20 ++++++++- clippy_lints/src/utils/paths.rs | 8 +++- tests/ui/panicking_macros.rs | 11 +++++ tests/ui/panicking_macros.stderr | 50 +++++++++++++++------ 9 files changed, 106 insertions(+), 54 deletions(-) diff --git a/clippy_lints/src/assertions_on_constants.rs b/clippy_lints/src/assertions_on_constants.rs index 982d5ecf8d02..a2ccb0369c4a 100644 --- a/clippy_lints/src/assertions_on_constants.rs +++ b/clippy_lints/src/assertions_on_constants.rs @@ -1,6 +1,5 @@ use crate::consts::{constant, Constant}; -use crate::utils::paths; -use crate::utils::{is_direct_expn_of, is_expn_of, match_function_call, snippet_opt, span_lint_and_help}; +use crate::utils::{is_direct_expn_of, is_expn_of, match_panic_call, snippet_opt, span_lint_and_help}; use if_chain::if_chain; use rustc_ast::ast::LitKind; use rustc_hir::{Expr, ExprKind, PatKind, UnOp}; @@ -133,7 +132,7 @@ fn match_assert_with_message<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) if let ExprKind::Block(ref inner_block, _) = block_expr.kind; if let Some(begin_panic_call) = &inner_block.expr; // function call - if let Some(args) = match_function_call(cx, begin_panic_call, &paths::BEGIN_PANIC); + if let Some(args) = match_panic_call(cx, begin_panic_call); if args.len() == 1; // bind the second argument of the `assert!` macro if it exists if let panic_message = snippet_opt(cx, args[0].span); diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 55904a0ec0a8..57702dafa6a0 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -1,7 +1,7 @@ //! checks for attributes use crate::utils::{ - first_line_of_span, is_present_in_source, match_def_path, paths, snippet_opt, span_lint, span_lint_and_help, + first_line_of_span, is_present_in_source, match_panic_def_id, snippet_opt, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, without_block_comments, }; use if_chain::if_chain; @@ -513,7 +513,7 @@ fn is_relevant_expr(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_> typeck_results .qpath_res(qpath, path_expr.hir_id) .opt_def_id() - .map_or(true, |fun_id| !match_def_path(cx, fun_id, &paths::BEGIN_PANIC)) + .map_or(true, |fun_id| !match_panic_def_id(cx, fun_id)) } else { true } diff --git a/clippy_lints/src/fallible_impl_from.rs b/clippy_lints/src/fallible_impl_from.rs index fe817fe94f2e..509a4a4e15f6 100644 --- a/clippy_lints/src/fallible_impl_from.rs +++ b/clippy_lints/src/fallible_impl_from.rs @@ -1,5 +1,7 @@ -use crate::utils::paths::{BEGIN_PANIC, BEGIN_PANIC_FMT, FROM_TRAIT}; -use crate::utils::{is_expn_of, is_type_diagnostic_item, match_def_path, method_chain_args, span_lint_and_then}; +use crate::utils::paths::FROM_TRAIT; +use crate::utils::{ + is_expn_of, is_type_diagnostic_item, match_def_path, match_panic_def_id, method_chain_args, span_lint_and_then, +}; use if_chain::if_chain; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; @@ -84,8 +86,7 @@ fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_items: &[h if let ExprKind::Call(ref func_expr, _) = expr.kind; if let ExprKind::Path(QPath::Resolved(_, ref path)) = func_expr.kind; if let Some(path_def_id) = path.res.opt_def_id(); - if match_def_path(self.lcx, path_def_id, &BEGIN_PANIC) || - match_def_path(self.lcx, path_def_id, &BEGIN_PANIC_FMT); + if match_panic_def_id(self.lcx, path_def_id); if is_expn_of(expr.span, "unreachable").is_none(); then { self.result.push(expr.span); diff --git a/clippy_lints/src/implicit_return.rs b/clippy_lints/src/implicit_return.rs index 22c4fef32a32..ed7f3b9293db 100644 --- a/clippy_lints/src/implicit_return.rs +++ b/clippy_lints/src/implicit_return.rs @@ -1,8 +1,4 @@ -use crate::utils::{ - fn_has_unsatisfiable_preds, match_def_path, - paths::{BEGIN_PANIC, BEGIN_PANIC_FMT}, - snippet_opt, span_lint_and_then, -}; +use crate::utils::{fn_has_unsatisfiable_preds, match_panic_def_id, snippet_opt, span_lint_and_then}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::intravisit::FnKind; @@ -109,8 +105,7 @@ fn expr_match(cx: &LateContext<'_>, expr: &Expr<'_>) { if_chain! { if let ExprKind::Path(qpath) = &expr.kind; if let Some(path_def_id) = cx.qpath_res(qpath, expr.hir_id).opt_def_id(); - if match_def_path(cx, path_def_id, &BEGIN_PANIC) || - match_def_path(cx, path_def_id, &BEGIN_PANIC_FMT); + if match_panic_def_id(cx, path_def_id); then { } else { lint(cx, expr.span, expr.span, LINT_RETURN) diff --git a/clippy_lints/src/panic_unimplemented.rs b/clippy_lints/src/panic_unimplemented.rs index 6379dffd22e3..3d888fe73257 100644 --- a/clippy_lints/src/panic_unimplemented.rs +++ b/clippy_lints/src/panic_unimplemented.rs @@ -1,4 +1,4 @@ -use crate::utils::{is_direct_expn_of, is_expn_of, match_function_call, paths, span_lint}; +use crate::utils::{is_direct_expn_of, is_expn_of, match_panic_call, span_lint}; use if_chain::if_chain; use rustc_ast::ast::LitKind; use rustc_hir::{Expr, ExprKind}; @@ -93,27 +93,27 @@ declare_lint_pass!(PanicUnimplemented => [PANIC_PARAMS, UNIMPLEMENTED, UNREACHAB impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if_chain! { - if let ExprKind::Block(ref block, _) = expr.kind; - if let Some(ref ex) = block.expr; - if let Some(params) = match_function_call(cx, ex, &paths::BEGIN_PANIC) - .or_else(|| match_function_call(cx, ex, &paths::BEGIN_PANIC_FMT)); - then { - let span = get_outer_span(expr); - if is_expn_of(expr.span, "unimplemented").is_some() { - span_lint(cx, UNIMPLEMENTED, span, - "`unimplemented` should not be present in production code"); - } else if is_expn_of(expr.span, "todo").is_some() { - span_lint(cx, TODO, span, - "`todo` should not be present in production code"); - } else if is_expn_of(expr.span, "unreachable").is_some() { - span_lint(cx, UNREACHABLE, span, - "`unreachable` should not be present in production code"); - } else if is_expn_of(expr.span, "panic").is_some() { - span_lint(cx, PANIC, span, - "`panic` should not be present in production code"); - match_panic(params, expr, cx); - } + if let Some(params) = match_panic_call(cx, expr) { + let span = get_outer_span(expr); + if is_expn_of(expr.span, "unimplemented").is_some() { + span_lint( + cx, + UNIMPLEMENTED, + span, + "`unimplemented` should not be present in production code", + ); + } else if is_expn_of(expr.span, "todo").is_some() { + span_lint(cx, TODO, span, "`todo` should not be present in production code"); + } else if is_expn_of(expr.span, "unreachable").is_some() { + span_lint( + cx, + UNREACHABLE, + span, + "`unreachable` should not be present in production code", + ); + } else if is_expn_of(expr.span, "panic").is_some() { + span_lint(cx, PANIC, span, "`panic` should not be present in production code"); + match_panic(params, expr, cx); } } } diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 0d43fd0392eb..a68262d56c64 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -1196,7 +1196,7 @@ pub fn has_iter_method(cx: &LateContext<'_>, probably_ref_ty: Ty<'_>) -> Option< /// Usage: /// /// ```rust,ignore -/// if let Some(args) = match_function_call(cx, begin_panic_call, &paths::BEGIN_PANIC); +/// if let Some(args) = match_function_call(cx, cmp_max_call, &paths::CMP_MAX); /// ``` pub fn match_function_call<'tcx>( cx: &LateContext<'tcx>, @@ -1231,6 +1231,24 @@ pub fn match_def_path<'tcx>(cx: &LateContext<'tcx>, did: DefId, syms: &[&str]) - cx.match_def_path(did, &syms) } +pub fn match_panic_call<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx [Expr<'tcx>]> { + match_function_call(cx, expr, &paths::BEGIN_PANIC) + .or_else(|| match_function_call(cx, expr, &paths::BEGIN_PANIC_FMT)) + .or_else(|| match_function_call(cx, expr, &paths::PANIC_ANY)) + .or_else(|| match_function_call(cx, expr, &paths::PANICKING_PANIC)) + .or_else(|| match_function_call(cx, expr, &paths::PANICKING_PANIC_FMT)) + .or_else(|| match_function_call(cx, expr, &paths::PANICKING_PANIC_STR)) +} + +pub fn match_panic_def_id(cx: &LateContext<'_>, did: DefId) -> bool { + match_def_path(cx, did, &paths::BEGIN_PANIC) + || match_def_path(cx, did, &paths::BEGIN_PANIC_FMT) + || match_def_path(cx, did, &paths::PANIC_ANY) + || match_def_path(cx, did, &paths::PANICKING_PANIC) + || match_def_path(cx, did, &paths::PANICKING_PANIC_FMT) + || match_def_path(cx, did, &paths::PANICKING_PANIC_STR) +} + /// Returns the list of condition expressions and the list of blocks in a /// sequence of `if/else`. /// E.g., this returns `([a, b], [c, d, e])` for the expression diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs index 1ad8c6029860..8f5fbfd9f846 100644 --- a/clippy_lints/src/utils/paths.rs +++ b/clippy_lints/src/utils/paths.rs @@ -8,8 +8,8 @@ pub const ANY_TRAIT: [&str; 3] = ["std", "any", "Any"]; pub const ARC_PTR_EQ: [&str; 4] = ["alloc", "sync", "Arc", "ptr_eq"]; pub const ASMUT_TRAIT: [&str; 3] = ["core", "convert", "AsMut"]; pub const ASREF_TRAIT: [&str; 3] = ["core", "convert", "AsRef"]; -pub const BEGIN_PANIC: [&str; 3] = ["std", "panicking", "begin_panic"]; -pub const BEGIN_PANIC_FMT: [&str; 3] = ["std", "panicking", "begin_panic_fmt"]; +pub(super) const BEGIN_PANIC: [&str; 3] = ["std", "panicking", "begin_panic"]; +pub(super) const BEGIN_PANIC_FMT: [&str; 3] = ["std", "panicking", "begin_panic_fmt"]; pub const BINARY_HEAP: [&str; 4] = ["alloc", "collections", "binary_heap", "BinaryHeap"]; pub const BORROW_TRAIT: [&str; 3] = ["core", "borrow", "Borrow"]; pub const BOX: [&str; 3] = ["alloc", "boxed", "Box"]; @@ -78,6 +78,10 @@ pub const ORD: [&str; 3] = ["core", "cmp", "Ord"]; pub const OS_STRING: [&str; 4] = ["std", "ffi", "os_str", "OsString"]; pub const OS_STRING_AS_OS_STR: [&str; 5] = ["std", "ffi", "os_str", "OsString", "as_os_str"]; pub const OS_STR_TO_OS_STRING: [&str; 5] = ["std", "ffi", "os_str", "OsStr", "to_os_string"]; +pub(super) const PANICKING_PANIC: [&str; 3] = ["core", "panicking", "panic"]; +pub(super) const PANICKING_PANIC_FMT: [&str; 3] = ["core", "panicking", "panic_fmt"]; +pub(super) const PANICKING_PANIC_STR: [&str; 3] = ["core", "panicking", "panic_str"]; +pub(super) const PANIC_ANY: [&str; 3] = ["std", "panic", "panic_any"]; pub const PARKING_LOT_MUTEX_GUARD: [&str; 2] = ["parking_lot", "MutexGuard"]; pub const PARKING_LOT_RWLOCK_READ_GUARD: [&str; 2] = ["parking_lot", "RwLockReadGuard"]; pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 2] = ["parking_lot", "RwLockWriteGuard"]; diff --git a/tests/ui/panicking_macros.rs b/tests/ui/panicking_macros.rs index f91ccfaed743..77fcb8dfd02f 100644 --- a/tests/ui/panicking_macros.rs +++ b/tests/ui/panicking_macros.rs @@ -1,6 +1,8 @@ #![warn(clippy::unimplemented, clippy::unreachable, clippy::todo, clippy::panic)] #![allow(clippy::assertions_on_constants)] +extern crate core; + fn panic() { let a = 2; panic!(); @@ -33,9 +35,18 @@ fn unreachable() { let b = a + 2; } +fn core_versions() { + use core::{panic, todo, unimplemented, unreachable}; + panic!(); + todo!(); + unimplemented!(); + unreachable!(); +} + fn main() { panic(); todo(); unimplemented(); unreachable(); + core_versions(); } diff --git a/tests/ui/panicking_macros.stderr b/tests/ui/panicking_macros.stderr index 37c11d72a574..83234c0ed92c 100644 --- a/tests/ui/panicking_macros.stderr +++ b/tests/ui/panicking_macros.stderr @@ -1,5 +1,5 @@ error: `panic` should not be present in production code - --> $DIR/panicking_macros.rs:6:5 + --> $DIR/panicking_macros.rs:8:5 | LL | panic!(); | ^^^^^^^^^ @@ -7,7 +7,7 @@ LL | panic!(); = note: `-D clippy::panic` implied by `-D warnings` error: `panic` should not be present in production code - --> $DIR/panicking_macros.rs:7:5 + --> $DIR/panicking_macros.rs:9:5 | LL | panic!("message"); | ^^^^^^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | panic!("message"); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `panic` should not be present in production code - --> $DIR/panicking_macros.rs:8:5 + --> $DIR/panicking_macros.rs:10:5 | LL | panic!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | panic!("{} {}", "panic with", "multiple arguments"); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `todo` should not be present in production code - --> $DIR/panicking_macros.rs:14:5 + --> $DIR/panicking_macros.rs:16:5 | LL | todo!(); | ^^^^^^^^ @@ -31,19 +31,19 @@ LL | todo!(); = note: `-D clippy::todo` implied by `-D warnings` error: `todo` should not be present in production code - --> $DIR/panicking_macros.rs:15:5 + --> $DIR/panicking_macros.rs:17:5 | LL | todo!("message"); | ^^^^^^^^^^^^^^^^^ error: `todo` should not be present in production code - --> $DIR/panicking_macros.rs:16:5 + --> $DIR/panicking_macros.rs:18:5 | LL | todo!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `unimplemented` should not be present in production code - --> $DIR/panicking_macros.rs:22:5 + --> $DIR/panicking_macros.rs:24:5 | LL | unimplemented!(); | ^^^^^^^^^^^^^^^^^ @@ -51,19 +51,19 @@ LL | unimplemented!(); = note: `-D clippy::unimplemented` implied by `-D warnings` error: `unimplemented` should not be present in production code - --> $DIR/panicking_macros.rs:23:5 + --> $DIR/panicking_macros.rs:25:5 | LL | unimplemented!("message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `unimplemented` should not be present in production code - --> $DIR/panicking_macros.rs:24:5 + --> $DIR/panicking_macros.rs:26:5 | LL | unimplemented!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `unreachable` should not be present in production code - --> $DIR/panicking_macros.rs:30:5 + --> $DIR/panicking_macros.rs:32:5 | LL | unreachable!(); | ^^^^^^^^^^^^^^^ @@ -71,7 +71,7 @@ LL | unreachable!(); = note: `-D clippy::unreachable` implied by `-D warnings` error: `unreachable` should not be present in production code - --> $DIR/panicking_macros.rs:31:5 + --> $DIR/panicking_macros.rs:33:5 | LL | unreachable!("message"); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -79,10 +79,34 @@ LL | unreachable!("message"); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `unreachable` should not be present in production code - --> $DIR/panicking_macros.rs:32:5 + --> $DIR/panicking_macros.rs:34:5 | LL | unreachable!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 12 previous errors +error: `panic` should not be present in production code + --> $DIR/panicking_macros.rs:40:5 + | +LL | panic!(); + | ^^^^^^^^^ + +error: `todo` should not be present in production code + --> $DIR/panicking_macros.rs:41:5 + | +LL | todo!(); + | ^^^^^^^^ + +error: `unimplemented` should not be present in production code + --> $DIR/panicking_macros.rs:42:5 + | +LL | unimplemented!(); + | ^^^^^^^^^^^^^^^^^ + +error: `unreachable` should not be present in production code + --> $DIR/panicking_macros.rs:43:5 + | +LL | unreachable!(); + | ^^^^^^^^^^^^^^^ + +error: aborting due to 16 previous errors From 78faaef8de0ac1dcd11353ad0cad1c0f0a6d2a58 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 19 Nov 2020 18:13:32 +0100 Subject: [PATCH 2/4] Remove the clippy::panic-params lint. Rustc itself now warns for all cases that triggered this lint. --- clippy_lints/src/lib.rs | 3 -- clippy_lints/src/panic_unimplemented.rs | 46 ++----------------- tests/ui/panic.rs | 61 ------------------------- tests/ui/panic.stderr | 28 ------------ 4 files changed, 4 insertions(+), 134 deletions(-) delete mode 100644 tests/ui/panic.rs delete mode 100644 tests/ui/panic.stderr diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 126852df502e..19bf67d80c42 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -788,7 +788,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL, &panic_in_result_fn::PANIC_IN_RESULT_FN, &panic_unimplemented::PANIC, - &panic_unimplemented::PANIC_PARAMS, &panic_unimplemented::TODO, &panic_unimplemented::UNIMPLEMENTED, &panic_unimplemented::UNREACHABLE, @@ -1499,7 +1498,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&open_options::NONSENSICAL_OPEN_OPTIONS), LintId::of(&option_env_unwrap::OPTION_ENV_UNWRAP), LintId::of(&overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL), - LintId::of(&panic_unimplemented::PANIC_PARAMS), LintId::of(&partialeq_ne_impl::PARTIALEQ_NE_IMPL), LintId::of(&precedence::PRECEDENCE), LintId::of(&ptr::CMP_NULL), @@ -1666,7 +1664,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST), LintId::of(&non_expressive_names::JUST_UNDERSCORES_AND_DIGITS), LintId::of(&non_expressive_names::MANY_SINGLE_CHAR_NAMES), - LintId::of(&panic_unimplemented::PANIC_PARAMS), LintId::of(&ptr::CMP_NULL), LintId::of(&ptr::PTR_ARG), LintId::of(&ptr_eq::PTR_EQ), diff --git a/clippy_lints/src/panic_unimplemented.rs b/clippy_lints/src/panic_unimplemented.rs index 3d888fe73257..8b10d0716471 100644 --- a/clippy_lints/src/panic_unimplemented.rs +++ b/clippy_lints/src/panic_unimplemented.rs @@ -1,30 +1,10 @@ -use crate::utils::{is_direct_expn_of, is_expn_of, match_panic_call, span_lint}; +use crate::utils::{is_expn_of, match_panic_call, span_lint}; use if_chain::if_chain; -use rustc_ast::ast::LitKind; -use rustc_hir::{Expr, ExprKind}; +use rustc_hir::Expr; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::Span; -declare_clippy_lint! { - /// **What it does:** Checks for missing parameters in `panic!`. - /// - /// **Why is this bad?** Contrary to the `format!` family of macros, there are - /// two forms of `panic!`: if there are no parameters given, the first argument - /// is not a format string and used literally. So while `format!("{}")` will - /// fail to compile, `panic!("{}")` will not. - /// - /// **Known problems:** None. - /// - /// **Example:** - /// ```no_run - /// panic!("This `panic!` is probably missing a parameter there: {}"); - /// ``` - pub PANIC_PARAMS, - style, - "missing parameters in `panic!` calls" -} - declare_clippy_lint! { /// **What it does:** Checks for usage of `panic!`. /// @@ -89,11 +69,11 @@ declare_clippy_lint! { "`unreachable!` should not be present in production code" } -declare_lint_pass!(PanicUnimplemented => [PANIC_PARAMS, UNIMPLEMENTED, UNREACHABLE, TODO, PANIC]); +declare_lint_pass!(PanicUnimplemented => [UNIMPLEMENTED, UNREACHABLE, TODO, PANIC]); impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if let Some(params) = match_panic_call(cx, expr) { + if let Some(_) = match_panic_call(cx, expr) { let span = get_outer_span(expr); if is_expn_of(expr.span, "unimplemented").is_some() { span_lint( @@ -113,7 +93,6 @@ impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented { ); } else if is_expn_of(expr.span, "panic").is_some() { span_lint(cx, PANIC, span, "`panic` should not be present in production code"); - match_panic(params, expr, cx); } } } @@ -132,20 +111,3 @@ fn get_outer_span(expr: &Expr<'_>) -> Span { } } } - -fn match_panic(params: &[Expr<'_>], expr: &Expr<'_>, cx: &LateContext<'_>) { - if_chain! { - if let ExprKind::Lit(ref lit) = params[0].kind; - if is_direct_expn_of(expr.span, "panic").is_some(); - if let LitKind::Str(ref string, _) = lit.node; - let string = string.as_str().replace("{{", "").replace("}}", ""); - if let Some(par) = string.find('{'); - if string[par..].contains('}'); - if params[0].span.source_callee().is_none(); - if params[0].span.lo() != params[0].span.hi(); - then { - span_lint(cx, PANIC_PARAMS, params[0].span, - "you probably are missing some parameter in your format string"); - } - } -} diff --git a/tests/ui/panic.rs b/tests/ui/panic.rs deleted file mode 100644 index 6e004aa9a924..000000000000 --- a/tests/ui/panic.rs +++ /dev/null @@ -1,61 +0,0 @@ -#![warn(clippy::panic_params)] -#![allow(clippy::assertions_on_constants)] -fn missing() { - if true { - panic!("{}"); - } else if false { - panic!("{:?}"); - } else { - assert!(true, "here be missing values: {}"); - } - - panic!("{{{this}}}"); -} - -fn ok_single() { - panic!("foo bar"); -} - -fn ok_inner() { - // Test for #768 - assert!("foo bar".contains(&format!("foo {}", "bar"))); -} - -fn ok_multiple() { - panic!("{}", "This is {ok}"); -} - -fn ok_bracket() { - match 42 { - 1337 => panic!("{so is this"), - 666 => panic!("so is this}"), - _ => panic!("}so is that{"), - } -} - -const ONE: u32 = 1; - -fn ok_nomsg() { - assert!({ 1 == ONE }); - assert!(if 1 == ONE { ONE == 1 } else { false }); -} - -fn ok_escaped() { - panic!("{{ why should this not be ok? }}"); - panic!(" or {{ that ?"); - panic!(" or }} this ?"); - panic!(" {or {{ that ?"); - panic!(" }or }} this ?"); - panic!("{{ test }"); - panic!("{case }}"); -} - -fn main() { - missing(); - ok_single(); - ok_multiple(); - ok_bracket(); - ok_inner(); - ok_nomsg(); - ok_escaped(); -} diff --git a/tests/ui/panic.stderr b/tests/ui/panic.stderr deleted file mode 100644 index 1f8ff8ccf557..000000000000 --- a/tests/ui/panic.stderr +++ /dev/null @@ -1,28 +0,0 @@ -error: you probably are missing some parameter in your format string - --> $DIR/panic.rs:5:16 - | -LL | panic!("{}"); - | ^^^^ - | - = note: `-D clippy::panic-params` implied by `-D warnings` - -error: you probably are missing some parameter in your format string - --> $DIR/panic.rs:7:16 - | -LL | panic!("{:?}"); - | ^^^^^^ - -error: you probably are missing some parameter in your format string - --> $DIR/panic.rs:9:23 - | -LL | assert!(true, "here be missing values: {}"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: you probably are missing some parameter in your format string - --> $DIR/panic.rs:12:12 - | -LL | panic!("{{{this}}}"); - | ^^^^^^^^^^^^ - -error: aborting due to 4 previous errors - From 113c1476c923492ea1427b061458a6ab8faf8df8 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 19 Nov 2020 19:47:25 +0100 Subject: [PATCH 3/4] Clippy: Match on assert!() expansions without an inner block. --- clippy_lints/src/assertions_on_constants.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/assertions_on_constants.rs b/clippy_lints/src/assertions_on_constants.rs index a2ccb0369c4a..a52f0997d439 100644 --- a/clippy_lints/src/assertions_on_constants.rs +++ b/clippy_lints/src/assertions_on_constants.rs @@ -129,8 +129,11 @@ fn match_assert_with_message<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) if let ExprKind::Block(ref block, _) = arms[0].body.kind; if block.stmts.is_empty(); if let Some(block_expr) = &block.expr; - if let ExprKind::Block(ref inner_block, _) = block_expr.kind; - if let Some(begin_panic_call) = &inner_block.expr; + // inner block is optional. unwarp it if it exists, or use the expression as is otherwise. + if let Some(begin_panic_call) = match block_expr.kind { + ExprKind::Block(ref inner_block, _) => &inner_block.expr, + _ => &block.expr, + }; // function call if let Some(args) = match_panic_call(cx, begin_panic_call); if args.len() == 1; From dd4e471b3fb701312c2a3fabfba0011f239d4760 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Fri, 20 Nov 2020 09:37:47 +0100 Subject: [PATCH 4/4] Properly deprecate panic_params lint --- clippy_lints/src/deprecated_lints.rs | 5 +++++ clippy_lints/src/lib.rs | 4 ++++ src/lintlist/mod.rs | 7 ------- tests/ui/deprecated.rs | 1 + tests/ui/deprecated.stderr | 8 +++++++- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/clippy_lints/src/deprecated_lints.rs b/clippy_lints/src/deprecated_lints.rs index 461c6e31d3eb..1c3285ed701d 100644 --- a/clippy_lints/src/deprecated_lints.rs +++ b/clippy_lints/src/deprecated_lints.rs @@ -181,3 +181,8 @@ declare_deprecated_lint! { pub TEMPORARY_CSTRING_AS_PTR, "this lint has been uplifted to rustc and is now called `temporary_cstring_as_ptr`" } + +declare_deprecated_lint! { + pub PANIC_PARAMS, + "this lint has been uplifted to rustc and is now called `panic_fmt`" +} diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 19bf67d80c42..ff5d48469955 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -495,6 +495,10 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: "clippy::temporary_cstring_as_ptr", "this lint has been uplifted to rustc and is now called `temporary_cstring_as_ptr`", ); + store.register_removed( + "clippy::panic_params", + "this lint has been uplifted to rustc and is now called `panic_fmt`", + ); // end deprecated lints, do not remove this comment, it’s used in `update_lints` // begin register lints, do not remove this comment, it’s used in `update_lints` diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs index 702f9d86de62..213e5758659c 100644 --- a/src/lintlist/mod.rs +++ b/src/lintlist/mod.rs @@ -1831,13 +1831,6 @@ vec![ deprecation: None, module: "panic_in_result_fn", }, - Lint { - name: "panic_params", - group: "style", - desc: "missing parameters in `panic!` calls", - deprecation: None, - module: "panic_unimplemented", - }, Lint { name: "panicking_unwrap", group: "correctness", diff --git a/tests/ui/deprecated.rs b/tests/ui/deprecated.rs index 56755596c97f..4cbc5630d759 100644 --- a/tests/ui/deprecated.rs +++ b/tests/ui/deprecated.rs @@ -10,5 +10,6 @@ #[warn(clippy::regex_macro)] #[warn(clippy::drop_bounds)] #[warn(clippy::temporary_cstring_as_ptr)] +#[warn(clippy::panic_params)] fn main() {} diff --git a/tests/ui/deprecated.stderr b/tests/ui/deprecated.stderr index 37b726fc00f1..a348d01d734f 100644 --- a/tests/ui/deprecated.stderr +++ b/tests/ui/deprecated.stderr @@ -72,11 +72,17 @@ error: lint `clippy::temporary_cstring_as_ptr` has been removed: `this lint has LL | #[warn(clippy::temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: lint `clippy::panic_params` has been removed: `this lint has been uplifted to rustc and is now called `panic_fmt`` + --> $DIR/deprecated.rs:13:8 + | +LL | #[warn(clippy::panic_params)] + | ^^^^^^^^^^^^^^^^^^^^ + error: lint `clippy::str_to_string` has been removed: `using `str::to_string` is common even today and specialization will likely happen soon` --> $DIR/deprecated.rs:1:8 | LL | #[warn(clippy::str_to_string)] | ^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 13 previous errors +error: aborting due to 14 previous errors