From b1f89ee02ff05d559a27949601bef628e498b128 Mon Sep 17 00:00:00 2001 From: Mateusz Gacek <96mateusz.gacek@gmail.com> Date: Wed, 17 Mar 2021 20:29:31 +0100 Subject: [PATCH] or_fun_call: trigger on unsafe blocks --- clippy_lints/src/methods/or_fun_call.rs | 13 +++++++++++-- tests/ui/or_fun_call.fixed | 14 ++++++++++++++ tests/ui/or_fun_call.rs | 14 ++++++++++++++ tests/ui/or_fun_call.stderr | 20 +++++++++++++++++++- 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/methods/or_fun_call.rs b/clippy_lints/src/methods/or_fun_call.rs index 1b43802a0..22df3e028 100644 --- a/clippy_lints/src/methods/or_fun_call.rs +++ b/clippy_lints/src/methods/or_fun_call.rs @@ -6,6 +6,7 @@ use clippy_utils::ty::{implements_trait, is_type_diagnostic_item, match_type}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir as hir; +use rustc_hir::{BlockCheckMode, UnsafeSource}; use rustc_lint::LateContext; use rustc_middle::ty; use rustc_span::source_map::Span; @@ -154,7 +155,6 @@ pub(super) fn check<'tcx>( } } } - if args.len() == 2 { match args[1].kind { hir::ExprKind::Call(ref fun, ref or_args) => { @@ -167,7 +167,16 @@ pub(super) fn check<'tcx>( hir::ExprKind::Index(..) | hir::ExprKind::MethodCall(..) => { check_general_case(cx, name, method_span, &args[0], &args[1], expr.span, None); }, - _ => {}, + hir::ExprKind::Block(block, _) => { + if let BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) = block.rules { + if let Some(block_expr) = block.expr { + if let hir::ExprKind::MethodCall(..) = block_expr.kind { + check_general_case(cx, name, method_span, &args[0], &args[1], expr.span, None); + } + } + } + }, + _ => (), } } } diff --git a/tests/ui/or_fun_call.fixed b/tests/ui/or_fun_call.fixed index 64347cae5..660245f10 100644 --- a/tests/ui/or_fun_call.fixed +++ b/tests/ui/or_fun_call.fixed @@ -132,4 +132,18 @@ fn f() -> Option<()> { Some(()) } +mod issue6675 { + unsafe fn foo() { + let mut s = "test".to_owned(); + None.unwrap_or_else(|| s.as_mut_vec()); + } + + fn bar() { + let mut s = "test".to_owned(); + None.unwrap_or_else(|| unsafe { s.as_mut_vec() }); + #[rustfmt::skip] + None.unwrap_or_else(|| unsafe { s.as_mut_vec() }); + } +} + fn main() {} diff --git a/tests/ui/or_fun_call.rs b/tests/ui/or_fun_call.rs index 7faab0017..c589b170b 100644 --- a/tests/ui/or_fun_call.rs +++ b/tests/ui/or_fun_call.rs @@ -132,4 +132,18 @@ fn f() -> Option<()> { Some(()) } +mod issue6675 { + unsafe fn foo() { + let mut s = "test".to_owned(); + None.unwrap_or(s.as_mut_vec()); + } + + fn bar() { + let mut s = "test".to_owned(); + None.unwrap_or(unsafe { s.as_mut_vec() }); + #[rustfmt::skip] + None.unwrap_or( unsafe { s.as_mut_vec() } ); + } +} + fn main() {} diff --git a/tests/ui/or_fun_call.stderr b/tests/ui/or_fun_call.stderr index 1e2bfd490..d63b34435 100644 --- a/tests/ui/or_fun_call.stderr +++ b/tests/ui/or_fun_call.stderr @@ -114,5 +114,23 @@ error: use of `or` followed by a function call LL | .or(Some(Bar(b, Duration::from_secs(2)))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_else(|| Some(Bar(b, Duration::from_secs(2))))` -error: aborting due to 19 previous errors +error: use of `unwrap_or` followed by a function call + --> $DIR/or_fun_call.rs:138:14 + | +LL | None.unwrap_or(s.as_mut_vec()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| s.as_mut_vec())` + +error: use of `unwrap_or` followed by a function call + --> $DIR/or_fun_call.rs:143:14 + | +LL | None.unwrap_or(unsafe { s.as_mut_vec() }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| unsafe { s.as_mut_vec() })` + +error: use of `unwrap_or` followed by a function call + --> $DIR/or_fun_call.rs:145:14 + | +LL | None.unwrap_or( unsafe { s.as_mut_vec() } ); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| unsafe { s.as_mut_vec() })` + +error: aborting due to 22 previous errors