diff --git a/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs b/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs index a1e44668e1adc..98ee8a9a8806c 100644 --- a/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs +++ b/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs @@ -1,12 +1,12 @@ -use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::last_path_segment; use clippy_utils::ty::{implements_trait, is_type_diagnostic_item}; -use if_chain::if_chain; - use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; use rustc_lint::LateLintPass; use rustc_middle::ty; +use rustc_middle::ty::print::with_forced_trimmed_paths; +use rustc_middle::ty::GenericArgKind; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::sym; @@ -15,8 +15,8 @@ declare_clippy_lint! { /// This lint warns when you use `Arc` with a type that does not implement `Send` or `Sync`. /// /// ### Why is this bad? - /// Wrapping a type in Arc doesn't add thread safety to the underlying data, so data races - /// could occur when touching the underlying data. + /// `Arc` is only `Send`/`Sync` when `T` is [both `Send` and `Sync`](https://doc.rust-lang.org/std/sync/struct.Arc.html#impl-Send-for-Arc%3CT%3E), + /// either `T` should be made `Send + Sync` or an `Rc` should be used instead of an `Arc` /// /// ### Example /// ```rust @@ -24,16 +24,17 @@ declare_clippy_lint! { /// # use std::sync::Arc; /// /// fn main() { - /// // This is safe, as `i32` implements `Send` and `Sync`. + /// // This is fine, as `i32` implements `Send` and `Sync`. /// let a = Arc::new(42); /// - /// // This is not safe, as `RefCell` does not implement `Sync`. + /// // `RefCell` is `!Sync`, so either the `Arc` should be replaced with an `Rc` + /// // or the `RefCell` replaced with something like a `RwLock` /// let b = Arc::new(RefCell::new(42)); /// } /// ``` #[clippy::version = "1.72.0"] pub ARC_WITH_NON_SEND_SYNC, - correctness, + suspicious, "using `Arc` with a type that does not implement `Send` or `Sync`" } declare_lint_pass!(ArcWithNonSendSync => [ARC_WITH_NON_SEND_SYNC]); @@ -41,32 +42,38 @@ declare_lint_pass!(ArcWithNonSendSync => [ARC_WITH_NON_SEND_SYNC]); impl LateLintPass<'_> for ArcWithNonSendSync { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { let ty = cx.typeck_results().expr_ty(expr); - if_chain! { - if is_type_diagnostic_item(cx, ty, sym::Arc); - if let ExprKind::Call(func, [arg]) = expr.kind; - if let ExprKind::Path(func_path) = func.kind; - if last_path_segment(&func_path).ident.name == sym::new; - if let arg_ty = cx.typeck_results().expr_ty(arg); - if !matches!(arg_ty.kind(), ty::Param(_)); - if !cx.tcx - .lang_items() - .sync_trait() - .map_or(false, |id| implements_trait(cx, arg_ty, id, &[])) || - !cx.tcx - .get_diagnostic_item(sym::Send) - .map_or(false, |id| implements_trait(cx, arg_ty, id, &[])); + if is_type_diagnostic_item(cx, ty, sym::Arc) + && let ExprKind::Call(func, [arg]) = expr.kind + && let ExprKind::Path(func_path) = func.kind + && last_path_segment(&func_path).ident.name == sym::new + && let arg_ty = cx.typeck_results().expr_ty(arg) + // make sure that the type is not and does not contain any type parameters + && arg_ty.walk().all(|arg| { + !matches!(arg.unpack(), GenericArgKind::Type(ty) if matches!(ty.kind(), ty::Param(_))) + }) + && let Some(send) = cx.tcx.get_diagnostic_item(sym::Send) + && let Some(sync) = cx.tcx.lang_items().sync_trait() + && let [is_send, is_sync] = [send, sync].map(|id| implements_trait(cx, arg_ty, id, &[])) + && !(is_send && is_sync) + { + span_lint_and_then( + cx, + ARC_WITH_NON_SEND_SYNC, + expr.span, + "usage of an `Arc` that is not `Send` or `Sync`", + |diag| with_forced_trimmed_paths!({ + if !is_send { + diag.note(format!("the trait `Send` is not implemented for `{arg_ty}`")); + } + if !is_sync { + diag.note(format!("the trait `Sync` is not implemented for `{arg_ty}`")); + } + + diag.note(format!("required for `{ty}` to implement `Send` and `Sync`")); - then { - span_lint_and_help( - cx, - ARC_WITH_NON_SEND_SYNC, - expr.span, - "usage of `Arc` where `T` is not `Send` or `Sync`", - None, - "consider using `Rc` instead or wrapping `T` in a std::sync type like \ - `Mutex`", - ); - } + diag.help("consider using an `Rc` instead or wrapping the inner type with a `Mutex`"); + } + )); } } } diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 73556c1053ecd..12f2f37e3c258 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -1296,8 +1296,8 @@ fn referent_used_exactly_once<'tcx>( possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>, reference: &Expr<'tcx>, ) -> bool { - let mir = enclosing_mir(cx.tcx, reference.hir_id); - if let Some(local) = expr_local(cx.tcx, reference) + if let Some(mir) = enclosing_mir(cx.tcx, reference.hir_id) + && let Some(local) = expr_local(cx.tcx, reference) && let [location] = *local_assignments(mir, local).as_slice() && let Some(statement) = mir.basic_blocks[location.block].statements.get(location.statement_index) && let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs index 7877f6a386cb3..ea9b894b63a3e 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs @@ -2,6 +2,8 @@ use clippy_utils::{diagnostics::span_lint_and_then, is_res_lang_ctor, last_path_ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_middle::ty::print::with_forced_trimmed_paths; use super::UNNECESSARY_LITERAL_UNWRAP; @@ -21,6 +23,7 @@ fn get_ty_from_args<'a>(args: Option<&'a [hir::GenericArg<'a>]>, index: usize) - } } +#[expect(clippy::too_many_lines)] pub(super) fn check( cx: &LateContext<'_>, expr: &hir::Expr<'_>, @@ -62,6 +65,34 @@ pub(super) fn check( (expr.span.with_hi(args[0].span.lo()), "panic!(".to_string()), (expr.span.with_lo(args[0].span.hi()), ")".to_string()), ]), + ("None", "unwrap_or_default", _) => { + let ty = cx.typeck_results().expr_ty(expr); + let default_ty_string = if let ty::Adt(def, ..) = ty.kind() { + with_forced_trimmed_paths!(format!("{}", cx.tcx.def_path_str(def.did()))) + } else { + "Default".to_string() + }; + Some(vec![(expr.span, format!("{default_ty_string}::default()"))]) + }, + ("None", "unwrap_or", _) => Some(vec![ + (expr.span.with_hi(args[0].span.lo()), String::new()), + (expr.span.with_lo(args[0].span.hi()), String::new()), + ]), + ("None", "unwrap_or_else", _) => match args[0].kind { + hir::ExprKind::Closure(hir::Closure { + fn_decl: + hir::FnDecl { + output: hir::FnRetTy::DefaultReturn(span) | hir::FnRetTy::Return(hir::Ty { span, .. }), + .. + }, + .. + }) => Some(vec![ + (expr.span.with_hi(span.hi()), String::new()), + (expr.span.with_lo(args[0].span.hi()), String::new()), + ]), + _ => None, + }, + _ if call_args.is_empty() => None, (_, _, Some(_)) => None, ("Ok", "unwrap_err", None) | ("Err", "unwrap", None) => Some(vec![ ( diff --git a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs index 1138d1163a4a9..497514fbcd606 100644 --- a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs +++ b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs @@ -207,11 +207,10 @@ impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug { if let ItemKind::Impl(Impl { of_trait: Some(trait_ref), self_ty, items, .. }) = item.kind && let Res::Def(DefKind::Trait, trait_def_id) = trait_ref.path.res && let TyKind::Path(QPath::Resolved(_, self_path)) = &self_ty.kind - // don't trigger if self is a generic parameter, e.g. `impl Debug for T` - // this can only happen in core itself, where the trait is defined, - // but it caused ICEs in the past: - // https://github.com/rust-lang/rust-clippy/issues/10887 - && !matches!(self_path.res, Res::Def(DefKind::TyParam, _)) + // make sure that the self type is either a struct, an enum or a union + // this prevents ICEs such as when self is a type parameter or a primitive type + // (see #10887, #11063) + && let Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, self_path_did) = self_path.res && cx.match_def_path(trait_def_id, &[sym::core, sym::fmt, sym::Debug]) // don't trigger if this impl was derived && !cx.tcx.has_attr(item.owner_id, sym::automatically_derived) @@ -222,7 +221,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug { && let body = cx.tcx.hir().body(*body_id) && let ExprKind::Block(block, _) = body.value.kind // inspect `self` - && let self_ty = cx.tcx.type_of(self_path.res.def_id()).skip_binder().peel_refs() + && let self_ty = cx.tcx.type_of(self_path_did).skip_binder().peel_refs() && let Some(self_adt) = self_ty.ty_adt_def() && let Some(self_def_id) = self_adt.did().as_local() && let Some(Node::Item(self_item)) = cx.tcx.hir().find_by_def_id(self_def_id) diff --git a/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs b/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs index 8e9234bba3c86..3e963d7989280 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs @@ -1,6 +1,8 @@ use clippy_utils::diagnostics::span_lint; +use clippy_utils::is_lint_allowed; use rustc_ast::LitKind; use rustc_hir as hir; +use rustc_hir::def::DefKind; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::Ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -45,8 +47,8 @@ fn is_same_type<'tcx>(cx: &LateContext<'tcx>, ty_resolved_path: hir::def::Res, f return primty.name() == func_return_type_sym; } - // type annotation is any other non generic type - if let hir::def::Res::Def(_, defid) = ty_resolved_path + // type annotation is a non generic type + if let hir::def::Res::Def(DefKind::Struct | DefKind::Union | DefKind::Enum, defid) = ty_resolved_path && let Some(annotation_ty) = cx.tcx.type_of(defid).no_bound_vars() { return annotation_ty == func_return_type; @@ -130,8 +132,9 @@ fn extract_primty(ty_kind: &hir::TyKind<'_>) -> Option { impl LateLintPass<'_> for RedundantTypeAnnotations { fn check_local<'tcx>(&mut self, cx: &LateContext<'tcx>, local: &'tcx rustc_hir::Local<'tcx>) { - // type annotation part - if !local.span.from_expansion() + if !is_lint_allowed(cx, REDUNDANT_TYPE_ANNOTATIONS, local.hir_id) + // type annotation part + && !local.span.from_expansion() && let Some(ty) = &local.ty // initialization part diff --git a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs index bd983306508ba..90eb45a0918f8 100644 --- a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs +++ b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs @@ -31,7 +31,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.72.0"] pub TUPLE_ARRAY_CONVERSIONS, - complexity, + nursery, "checks for tuple<=>array conversions that are not done with `.into()`" } impl_lint_pass!(TupleArrayConversions => [TUPLE_ARRAY_CONVERSIONS]); diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs index b6c11cfb35568..22de383ea4fe2 100644 --- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs +++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs @@ -6,6 +6,7 @@ use clippy_utils::ty::{is_copy, is_type_diagnostic_item, same_type_and_consts}; use clippy_utils::{get_parent_expr, is_trait_method, match_def_path, path_to_local, paths}; use if_chain::if_chain; use rustc_errors::Applicability; +use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::{BindingAnnotation, Expr, ExprKind, HirId, MatchSource, Node, PatKind}; use rustc_lint::{LateContext, LateLintPass}; @@ -40,6 +41,7 @@ declare_clippy_lint! { #[derive(Default)] pub struct UselessConversion { try_desugar_arm: Vec, + expn_depth: u32, } impl_lint_pass!(UselessConversion => [USELESS_CONVERSION]); @@ -106,6 +108,7 @@ fn into_iter_deep_call<'hir>(cx: &LateContext<'_>, mut expr: &'hir Expr<'hir>) - impl<'tcx> LateLintPass<'tcx> for UselessConversion { fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { if e.span.from_expansion() { + self.expn_depth += 1; return; } @@ -151,9 +154,14 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { { if let Some(parent) = get_parent_expr(cx, e) { let parent_fn = match parent.kind { - ExprKind::Call(recv, args) if let ExprKind::Path(ref qpath) = recv.kind => { - cx.qpath_res(qpath, recv.hir_id).opt_def_id() - .map(|did| (did, args, MethodOrFunction::Function)) + ExprKind::Call(recv, args) + if let ExprKind::Path(ref qpath) = recv.kind + && let Some(did) = cx.qpath_res(qpath, recv.hir_id).opt_def_id() + // make sure that the path indeed points to a fn-like item, so that + // `fn_sig` does not ICE. (see #11065) + && cx.tcx.opt_def_kind(did).is_some_and(DefKind::is_fn_like) => + { + Some((did, args, MethodOrFunction::Function)) } ExprKind::MethodCall(.., args, _) => { cx.typeck_results().type_dependent_def_id(parent.hir_id) @@ -169,6 +177,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { && let Some(&into_iter_param) = sig.inputs().get(kind.param_pos(arg_pos)) && let ty::Param(param) = into_iter_param.kind() && let Some(span) = into_iter_bound(cx, parent_fn_did, into_iter_did, param.index) + && self.expn_depth == 0 { // Get the "innermost" `.into_iter()` call, e.g. given this expression: // `foo.into_iter().into_iter()` @@ -304,5 +313,8 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { if Some(&e.hir_id) == self.try_desugar_arm.last() { self.try_desugar_arm.pop(); } + if e.span.from_expansion() { + self.expn_depth -= 1; + } } } diff --git a/src/tools/clippy/clippy_utils/src/mir/mod.rs b/src/tools/clippy/clippy_utils/src/mir/mod.rs index 26c0015e87e0f..131f3c0aa3946 100644 --- a/src/tools/clippy/clippy_utils/src/mir/mod.rs +++ b/src/tools/clippy/clippy_utils/src/mir/mod.rs @@ -101,21 +101,26 @@ pub fn used_exactly_once(mir: &rustc_middle::mir::Body<'_>, local: rustc_middle: /// Returns the `mir::Body` containing the node associated with `hir_id`. #[allow(clippy::module_name_repetitions)] -pub fn enclosing_mir(tcx: TyCtxt<'_>, hir_id: HirId) -> &Body<'_> { +pub fn enclosing_mir(tcx: TyCtxt<'_>, hir_id: HirId) -> Option<&Body<'_>> { let body_owner_local_def_id = tcx.hir().enclosing_body_owner(hir_id); - tcx.optimized_mir(body_owner_local_def_id.to_def_id()) + if tcx.hir().body_owner_kind(body_owner_local_def_id).is_fn_or_closure() { + Some(tcx.optimized_mir(body_owner_local_def_id.to_def_id())) + } else { + None + } } /// Tries to determine the `Local` corresponding to `expr`, if any. /// This function is expensive and should be used sparingly. pub fn expr_local(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> Option { - let mir = enclosing_mir(tcx, expr.hir_id); - mir.local_decls.iter_enumerated().find_map(|(local, local_decl)| { - if local_decl.source_info.span == expr.span { - Some(local) - } else { - None - } + enclosing_mir(tcx, expr.hir_id).and_then(|mir| { + mir.local_decls.iter_enumerated().find_map(|(local, local_decl)| { + if local_decl.source_info.span == expr.span { + Some(local) + } else { + None + } + }) }) } diff --git a/src/tools/clippy/tests/ui/arc_with_non_send_sync.rs b/src/tools/clippy/tests/ui/arc_with_non_send_sync.rs index ac786f68c123d..b6fcca0a7919e 100644 --- a/src/tools/clippy/tests/ui/arc_with_non_send_sync.rs +++ b/src/tools/clippy/tests/ui/arc_with_non_send_sync.rs @@ -7,11 +7,18 @@ fn foo(x: T) { // Should not lint - purposefully ignoring generic args. let a = Arc::new(x); } +fn issue11076() { + let a: Arc> = Arc::new(Vec::new()); +} fn main() { - // This is safe, as `i32` implements `Send` and `Sync`. - let a = Arc::new(42); + let _ = Arc::new(42); - // This is not safe, as `RefCell` does not implement `Sync`. - let b = Arc::new(RefCell::new(42)); + // !Sync + let _ = Arc::new(RefCell::new(42)); + let mutex = Mutex::new(1); + // !Send + let _ = Arc::new(mutex.lock().unwrap()); + // !Send + !Sync + let _ = Arc::new(&42 as *const i32); } diff --git a/src/tools/clippy/tests/ui/arc_with_non_send_sync.stderr b/src/tools/clippy/tests/ui/arc_with_non_send_sync.stderr index fc2fc5f93b13b..7633b38dfb597 100644 --- a/src/tools/clippy/tests/ui/arc_with_non_send_sync.stderr +++ b/src/tools/clippy/tests/ui/arc_with_non_send_sync.stderr @@ -1,11 +1,34 @@ -error: usage of `Arc` where `T` is not `Send` or `Sync` - --> $DIR/arc_with_non_send_sync.rs:16:13 +error: usage of an `Arc` that is not `Send` or `Sync` + --> $DIR/arc_with_non_send_sync.rs:18:13 | -LL | let b = Arc::new(RefCell::new(42)); +LL | let _ = Arc::new(RefCell::new(42)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: consider using `Rc` instead or wrapping `T` in a std::sync type like `Mutex` + = note: the trait `Sync` is not implemented for `RefCell` + = note: required for `Arc>` to implement `Send` and `Sync` + = help: consider using an `Rc` instead or wrapping the inner type with a `Mutex` = note: `-D clippy::arc-with-non-send-sync` implied by `-D warnings` -error: aborting due to previous error +error: usage of an `Arc` that is not `Send` or `Sync` + --> $DIR/arc_with_non_send_sync.rs:21:13 + | +LL | let _ = Arc::new(mutex.lock().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the trait `Send` is not implemented for `MutexGuard<'_, i32>` + = note: required for `Arc>` to implement `Send` and `Sync` + = help: consider using an `Rc` instead or wrapping the inner type with a `Mutex` + +error: usage of an `Arc` that is not `Send` or `Sync` + --> $DIR/arc_with_non_send_sync.rs:23:13 + | +LL | let _ = Arc::new(&42 as *const i32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the trait `Send` is not implemented for `*const i32` + = note: the trait `Sync` is not implemented for `*const i32` + = note: required for `Arc<*const i32>` to implement `Send` and `Sync` + = help: consider using an `Rc` instead or wrapping the inner type with a `Mutex` + +error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/crashes/ice-11065.rs b/src/tools/clippy/tests/ui/crashes/ice-11065.rs new file mode 100644 index 0000000000000..f5cf6b1cd77a2 --- /dev/null +++ b/src/tools/clippy/tests/ui/crashes/ice-11065.rs @@ -0,0 +1,19 @@ +#![warn(clippy::useless_conversion)] + +use std::iter::FromIterator; +use std::option::IntoIter as OptionIter; + +fn eq(a: T, b: T) -> bool { + a == b +} + +macro_rules! tests { + ($($expr:expr, $ty:ty, ($($test:expr),*);)+) => (pub fn main() {$({ + const C: $ty = $expr; + assert!(eq(C($($test),*), $expr($($test),*))); + })+}) +} + +tests! { + FromIterator::from_iter, fn(OptionIter) -> Vec, (Some(5).into_iter()); +} diff --git a/src/tools/clippy/tests/ui/needless_borrow.fixed b/src/tools/clippy/tests/ui/needless_borrow.fixed index 80cdb4e472d41..1dfbee150d789 100644 --- a/src/tools/clippy/tests/ui/needless_borrow.fixed +++ b/src/tools/clippy/tests/ui/needless_borrow.fixed @@ -492,3 +492,15 @@ mod issue_9782_method_variant { S.foo::<&[u8; 100]>(&a); } } + +mod issue_10535 { + static SOME_STATIC: String = String::new(); + + static UNIT: () = compute(&SOME_STATIC); + + pub const fn compute(_: T) + where + T: Copy, + { + } +} diff --git a/src/tools/clippy/tests/ui/needless_borrow.rs b/src/tools/clippy/tests/ui/needless_borrow.rs index 99f735127eb8e..3c0d73f5f0253 100644 --- a/src/tools/clippy/tests/ui/needless_borrow.rs +++ b/src/tools/clippy/tests/ui/needless_borrow.rs @@ -492,3 +492,15 @@ mod issue_9782_method_variant { S.foo::<&[u8; 100]>(&a); } } + +mod issue_10535 { + static SOME_STATIC: String = String::new(); + + static UNIT: () = compute(&SOME_STATIC); + + pub const fn compute(_: T) + where + T: Copy, + { + } +} diff --git a/src/tools/clippy/tests/ui/redundant_type_annotations.rs b/src/tools/clippy/tests/ui/redundant_type_annotations.rs index cc507b8d658ce..09dbd3c9b39e1 100644 --- a/src/tools/clippy/tests/ui/redundant_type_annotations.rs +++ b/src/tools/clippy/tests/ui/redundant_type_annotations.rs @@ -6,8 +6,8 @@ struct Cake { _data: T, } -fn make_something() -> T { - T::default() +fn make_something() -> T { + unimplemented!() } fn make_cake() -> Cake { @@ -117,7 +117,15 @@ fn test_non_locals() { let _closure_arg = |x: u32| x; } -fn test_complex_types() { +trait Trait { + type AssocTy; +} + +impl Trait for () { + type AssocTy = String; +} + +fn test_complex_types() { // Shouldn't be lint, since the literal will be i32 otherwise let _u8: u8 = 128; @@ -135,6 +143,10 @@ fn test_complex_types() { // Shouldn't be lint let _array: [u32; 2] = [8, 9]; + + let ty_param: T = make_something(); + + let assoc_ty: <() as Trait>::AssocTy = String::new(); } fn test_functions() { @@ -173,4 +185,6 @@ fn test_simple_types() { let _var: bool = false; } +fn issue11190() {} + fn main() {} diff --git a/src/tools/clippy/tests/ui/redundant_type_annotations.stderr b/src/tools/clippy/tests/ui/redundant_type_annotations.stderr index e8b2fe5c3847a..988ebe6372268 100644 --- a/src/tools/clippy/tests/ui/redundant_type_annotations.stderr +++ b/src/tools/clippy/tests/ui/redundant_type_annotations.stderr @@ -19,85 +19,85 @@ LL | let v: &Slice = self.return_a_ref_to_struct(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:143:5 + --> $DIR/redundant_type_annotations.rs:155:5 | LL | let _return: String = return_a_string(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:145:5 + --> $DIR/redundant_type_annotations.rs:157:5 | LL | let _return: Pie = return_a_struct(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:147:5 + --> $DIR/redundant_type_annotations.rs:159:5 | LL | let _return: Pizza = return_an_enum(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:149:5 + --> $DIR/redundant_type_annotations.rs:161:5 | LL | let _return: u32 = return_an_int(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:151:5 + --> $DIR/redundant_type_annotations.rs:163:5 | LL | let _return: String = String::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:153:5 + --> $DIR/redundant_type_annotations.rs:165:5 | LL | let new_pie: Pie = Pie::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:155:5 + --> $DIR/redundant_type_annotations.rs:167:5 | LL | let _return: u32 = new_pie.return_an_int(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:157:5 + --> $DIR/redundant_type_annotations.rs:169:5 | LL | let _return: u32 = Pie::associated_return_an_int(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:159:5 + --> $DIR/redundant_type_annotations.rs:171:5 | LL | let _return: String = Pie::associated_return_a_string(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:165:5 + --> $DIR/redundant_type_annotations.rs:177:5 | LL | let _var: u32 = u32::MAX; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:167:5 + --> $DIR/redundant_type_annotations.rs:179:5 | LL | let _var: u32 = 5_u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:169:5 + --> $DIR/redundant_type_annotations.rs:181:5 | LL | let _var: &str = "test"; | ^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:171:5 + --> $DIR/redundant_type_annotations.rs:183:5 | LL | let _var: &[u8] = b"test"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant type annotation - --> $DIR/redundant_type_annotations.rs:173:5 + --> $DIR/redundant_type_annotations.rs:185:5 | LL | let _var: bool = false; | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.fixed b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.fixed index 630a1bea3c879..44530d8b1e8df 100644 --- a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.fixed @@ -16,12 +16,23 @@ fn unwrap_option_some() { 1; } +#[rustfmt::skip] // force rustfmt not to remove braces in `|| { 234 }` fn unwrap_option_none() { let _val = panic!(); let _val = panic!("this always happens"); + let _val: String = String::default(); + let _val: u16 = 234; + let _val: u16 = 234; + let _val: u16 = { 234 }; + let _val: u16 = { 234 }; panic!(); panic!("this always happens"); + String::default(); + 234; + 234; + { 234 }; + { 234 }; } fn unwrap_result_ok() { diff --git a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.rs b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.rs index 14f92cb370f6a..b43e4d3a347ee 100644 --- a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.rs +++ b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.rs @@ -16,12 +16,23 @@ fn unwrap_option_some() { Some(1).expect("this never happens"); } +#[rustfmt::skip] // force rustfmt not to remove braces in `|| { 234 }` fn unwrap_option_none() { let _val = None::<()>.unwrap(); let _val = None::<()>.expect("this always happens"); + let _val: String = None.unwrap_or_default(); + let _val: u16 = None.unwrap_or(234); + let _val: u16 = None.unwrap_or_else(|| 234); + let _val: u16 = None.unwrap_or_else(|| { 234 }); + let _val: u16 = None.unwrap_or_else(|| -> u16 { 234 }); None::<()>.unwrap(); None::<()>.expect("this always happens"); + None::.unwrap_or_default(); + None::.unwrap_or(234); + None::.unwrap_or_else(|| 234); + None::.unwrap_or_else(|| { 234 }); + None::.unwrap_or_else(|| -> u16 { 234 }); } fn unwrap_result_ok() { diff --git a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr index 0c71ee053231c..905384bc8c222 100644 --- a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr @@ -48,13 +48,13 @@ LL + 1; | error: used `unwrap()` on `None` value - --> $DIR/unnecessary_literal_unwrap.rs:20:16 + --> $DIR/unnecessary_literal_unwrap.rs:21:16 | LL | let _val = None::<()>.unwrap(); | ^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap()`: `panic!()` error: used `expect()` on `None` value - --> $DIR/unnecessary_literal_unwrap.rs:21:16 + --> $DIR/unnecessary_literal_unwrap.rs:22:16 | LL | let _val = None::<()>.expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -64,14 +64,68 @@ help: remove the `None` and `expect()` LL | let _val = panic!("this always happens"); | ~~~~~~~ ~ +error: used `unwrap_or_default()` on `None` value + --> $DIR/unnecessary_literal_unwrap.rs:23:24 + | +LL | let _val: String = None.unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap_or_default()`: `String::default()` + +error: used `unwrap_or()` on `None` value + --> $DIR/unnecessary_literal_unwrap.rs:24:21 + | +LL | let _val: u16 = None.unwrap_or(234); + | ^^^^^^^^^^^^^^^^^^^ + | +help: remove the `None` and `unwrap_or()` + | +LL - let _val: u16 = None.unwrap_or(234); +LL + let _val: u16 = 234; + | + +error: used `unwrap_or_else()` on `None` value + --> $DIR/unnecessary_literal_unwrap.rs:25:21 + | +LL | let _val: u16 = None.unwrap_or_else(|| 234); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `None` and `unwrap_or_else()` + | +LL - let _val: u16 = None.unwrap_or_else(|| 234); +LL + let _val: u16 = 234; + | + +error: used `unwrap_or_else()` on `None` value + --> $DIR/unnecessary_literal_unwrap.rs:26:21 + | +LL | let _val: u16 = None.unwrap_or_else(|| { 234 }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `None` and `unwrap_or_else()` + | +LL - let _val: u16 = None.unwrap_or_else(|| { 234 }); +LL + let _val: u16 = { 234 }; + | + +error: used `unwrap_or_else()` on `None` value + --> $DIR/unnecessary_literal_unwrap.rs:27:21 + | +LL | let _val: u16 = None.unwrap_or_else(|| -> u16 { 234 }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `None` and `unwrap_or_else()` + | +LL - let _val: u16 = None.unwrap_or_else(|| -> u16 { 234 }); +LL + let _val: u16 = { 234 }; + | + error: used `unwrap()` on `None` value - --> $DIR/unnecessary_literal_unwrap.rs:23:5 + --> $DIR/unnecessary_literal_unwrap.rs:29:5 | LL | None::<()>.unwrap(); | ^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap()`: `panic!()` error: used `expect()` on `None` value - --> $DIR/unnecessary_literal_unwrap.rs:24:5 + --> $DIR/unnecessary_literal_unwrap.rs:30:5 | LL | None::<()>.expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -81,8 +135,62 @@ help: remove the `None` and `expect()` LL | panic!("this always happens"); | ~~~~~~~ ~ +error: used `unwrap_or_default()` on `None` value + --> $DIR/unnecessary_literal_unwrap.rs:31:5 + | +LL | None::.unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap_or_default()`: `String::default()` + +error: used `unwrap_or()` on `None` value + --> $DIR/unnecessary_literal_unwrap.rs:32:5 + | +LL | None::.unwrap_or(234); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `None` and `unwrap_or()` + | +LL - None::.unwrap_or(234); +LL + 234; + | + +error: used `unwrap_or_else()` on `None` value + --> $DIR/unnecessary_literal_unwrap.rs:33:5 + | +LL | None::.unwrap_or_else(|| 234); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `None` and `unwrap_or_else()` + | +LL - None::.unwrap_or_else(|| 234); +LL + 234; + | + +error: used `unwrap_or_else()` on `None` value + --> $DIR/unnecessary_literal_unwrap.rs:34:5 + | +LL | None::.unwrap_or_else(|| { 234 }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `None` and `unwrap_or_else()` + | +LL - None::.unwrap_or_else(|| { 234 }); +LL + { 234 }; + | + +error: used `unwrap_or_else()` on `None` value + --> $DIR/unnecessary_literal_unwrap.rs:35:5 + | +LL | None::.unwrap_or_else(|| -> u16 { 234 }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `None` and `unwrap_or_else()` + | +LL - None::.unwrap_or_else(|| -> u16 { 234 }); +LL + { 234 }; + | + error: used `unwrap()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap.rs:28:16 + --> $DIR/unnecessary_literal_unwrap.rs:39:16 | LL | let _val = Ok::<_, ()>(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -94,7 +202,7 @@ LL + let _val = 1; | error: used `expect()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap.rs:29:16 + --> $DIR/unnecessary_literal_unwrap.rs:40:16 | LL | let _val = Ok::<_, ()>(1).expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -106,7 +214,7 @@ LL + let _val = 1; | error: used `unwrap_err()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap.rs:30:16 + --> $DIR/unnecessary_literal_unwrap.rs:41:16 | LL | let _val = Ok::<_, ()>(1).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -117,7 +225,7 @@ LL | let _val = panic!("{:?}", 1); | ~~~~~~~~~~~~~~ ~ error: used `expect_err()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap.rs:31:16 + --> $DIR/unnecessary_literal_unwrap.rs:42:16 | LL | let _val = Ok::<_, ()>(1).expect_err("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -128,7 +236,7 @@ LL | let _val = panic!("{1}: {:?}", 1, "this always happens"); | ~~~~~~~~~~~~~~~~~~~ ~ error: used `unwrap()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap.rs:33:5 + --> $DIR/unnecessary_literal_unwrap.rs:44:5 | LL | Ok::<_, ()>(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -140,7 +248,7 @@ LL + 1; | error: used `expect()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap.rs:34:5 + --> $DIR/unnecessary_literal_unwrap.rs:45:5 | LL | Ok::<_, ()>(1).expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -152,7 +260,7 @@ LL + 1; | error: used `unwrap_err()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap.rs:35:5 + --> $DIR/unnecessary_literal_unwrap.rs:46:5 | LL | Ok::<_, ()>(1).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -163,7 +271,7 @@ LL | panic!("{:?}", 1); | ~~~~~~~~~~~~~~ ~ error: used `expect_err()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap.rs:36:5 + --> $DIR/unnecessary_literal_unwrap.rs:47:5 | LL | Ok::<_, ()>(1).expect_err("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -174,7 +282,7 @@ LL | panic!("{1}: {:?}", 1, "this always happens"); | ~~~~~~~~~~~~~~~~~~~ ~ error: used `unwrap_err()` on `Err` value - --> $DIR/unnecessary_literal_unwrap.rs:40:16 + --> $DIR/unnecessary_literal_unwrap.rs:51:16 | LL | let _val = Err::<(), _>(1).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -186,7 +294,7 @@ LL + let _val = 1; | error: used `expect_err()` on `Err` value - --> $DIR/unnecessary_literal_unwrap.rs:41:16 + --> $DIR/unnecessary_literal_unwrap.rs:52:16 | LL | let _val = Err::<(), _>(1).expect_err("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -198,7 +306,7 @@ LL + let _val = 1; | error: used `unwrap()` on `Err` value - --> $DIR/unnecessary_literal_unwrap.rs:42:16 + --> $DIR/unnecessary_literal_unwrap.rs:53:16 | LL | let _val = Err::<(), _>(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -209,7 +317,7 @@ LL | let _val = panic!("{:?}", 1); | ~~~~~~~~~~~~~~ ~ error: used `expect()` on `Err` value - --> $DIR/unnecessary_literal_unwrap.rs:43:16 + --> $DIR/unnecessary_literal_unwrap.rs:54:16 | LL | let _val = Err::<(), _>(1).expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +328,7 @@ LL | let _val = panic!("{1}: {:?}", 1, "this always happens"); | ~~~~~~~~~~~~~~~~~~~ ~ error: used `unwrap_err()` on `Err` value - --> $DIR/unnecessary_literal_unwrap.rs:45:5 + --> $DIR/unnecessary_literal_unwrap.rs:56:5 | LL | Err::<(), _>(1).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -232,7 +340,7 @@ LL + 1; | error: used `expect_err()` on `Err` value - --> $DIR/unnecessary_literal_unwrap.rs:46:5 + --> $DIR/unnecessary_literal_unwrap.rs:57:5 | LL | Err::<(), _>(1).expect_err("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -244,7 +352,7 @@ LL + 1; | error: used `unwrap()` on `Err` value - --> $DIR/unnecessary_literal_unwrap.rs:47:5 + --> $DIR/unnecessary_literal_unwrap.rs:58:5 | LL | Err::<(), _>(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -255,7 +363,7 @@ LL | panic!("{:?}", 1); | ~~~~~~~~~~~~~~ ~ error: used `expect()` on `Err` value - --> $DIR/unnecessary_literal_unwrap.rs:48:5 + --> $DIR/unnecessary_literal_unwrap.rs:59:5 | LL | Err::<(), _>(1).expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -266,7 +374,7 @@ LL | panic!("{1}: {:?}", 1, "this always happens"); | ~~~~~~~~~~~~~~~~~~~ ~ error: used `unwrap_or()` on `Some` value - --> $DIR/unnecessary_literal_unwrap.rs:52:16 + --> $DIR/unnecessary_literal_unwrap.rs:63:16 | LL | let _val = Some(1).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^ @@ -278,7 +386,7 @@ LL + let _val = 1; | error: used `unwrap_or_default()` on `Some` value - --> $DIR/unnecessary_literal_unwrap.rs:53:16 + --> $DIR/unnecessary_literal_unwrap.rs:64:16 | LL | let _val = Some(1).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -290,7 +398,7 @@ LL + let _val = 1; | error: used `unwrap_or_else()` on `Some` value - --> $DIR/unnecessary_literal_unwrap.rs:54:16 + --> $DIR/unnecessary_literal_unwrap.rs:65:16 | LL | let _val = Some(1).unwrap_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -302,7 +410,7 @@ LL + let _val = 1; | error: used `unwrap_or()` on `Some` value - --> $DIR/unnecessary_literal_unwrap.rs:56:5 + --> $DIR/unnecessary_literal_unwrap.rs:67:5 | LL | Some(1).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^ @@ -314,7 +422,7 @@ LL + 1; | error: used `unwrap_or_default()` on `Some` value - --> $DIR/unnecessary_literal_unwrap.rs:57:5 + --> $DIR/unnecessary_literal_unwrap.rs:68:5 | LL | Some(1).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -326,7 +434,7 @@ LL + 1; | error: used `unwrap_or_else()` on `Some` value - --> $DIR/unnecessary_literal_unwrap.rs:58:5 + --> $DIR/unnecessary_literal_unwrap.rs:69:5 | LL | Some(1).unwrap_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -338,7 +446,7 @@ LL + 1; | error: used `unwrap_or()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap.rs:62:16 + --> $DIR/unnecessary_literal_unwrap.rs:73:16 | LL | let _val = Ok::<_, ()>(1).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -350,7 +458,7 @@ LL + let _val = 1; | error: used `unwrap_or_default()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap.rs:63:16 + --> $DIR/unnecessary_literal_unwrap.rs:74:16 | LL | let _val = Ok::<_, ()>(1).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -362,7 +470,7 @@ LL + let _val = 1; | error: used `unwrap_or_else()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap.rs:64:16 + --> $DIR/unnecessary_literal_unwrap.rs:75:16 | LL | let _val = Ok::<_, ()>(1).unwrap_or_else(|_| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -374,7 +482,7 @@ LL + let _val = 1; | error: used `unwrap_or()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap.rs:66:5 + --> $DIR/unnecessary_literal_unwrap.rs:77:5 | LL | Ok::<_, ()>(1).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -386,7 +494,7 @@ LL + 1; | error: used `unwrap_or_default()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap.rs:67:5 + --> $DIR/unnecessary_literal_unwrap.rs:78:5 | LL | Ok::<_, ()>(1).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -398,7 +506,7 @@ LL + 1; | error: used `unwrap_or_else()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap.rs:68:5 + --> $DIR/unnecessary_literal_unwrap.rs:79:5 | LL | Ok::<_, ()>(1).unwrap_or_else(|_| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -409,5 +517,5 @@ LL - Ok::<_, ()>(1).unwrap_or_else(|_| 2); LL + 1; | -error: aborting due to 36 previous errors +error: aborting due to 46 previous errors diff --git a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap_unfixable.rs b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap_unfixable.rs index 711fdce39624e..41300aceb4153 100644 --- a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap_unfixable.rs +++ b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap_unfixable.rs @@ -21,6 +21,8 @@ fn unwrap_option_none() { let val = None::<()>; let _val2 = val.unwrap(); let _val2 = val.expect("this always happens"); + let _val3: u8 = None.unwrap_or_default(); + None::<()>.unwrap_or_default(); } fn unwrap_result_ok() { diff --git a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap_unfixable.stderr b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap_unfixable.stderr index feb9325b77a67..2d1270d47174f 100644 --- a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap_unfixable.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap_unfixable.stderr @@ -95,509 +95,521 @@ help: remove the `None` and `expect()` LL | let val = None::<()>; | ^^^^^^^^^^ +error: used `unwrap_or_default()` on `None` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:24:21 + | +LL | let _val3: u8 = None.unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap_or_default()`: `Default::default()` + +error: used `unwrap_or_default()` on `None` value + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:25:5 + | +LL | None::<()>.unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap_or_default()`: `Default::default()` + error: used `unwrap()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:28:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:30:17 | LL | let _val2 = val.unwrap(); | ^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:27:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:29:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `expect()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:29:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:31:17 | LL | let _val2 = val.expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `expect()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:27:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:29:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `unwrap_err()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:30:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:32:17 | LL | let _val2 = val.unwrap_err(); | ^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_err()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:27:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:29:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `expect_err()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:31:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:33:17 | LL | let _val2 = val.expect_err("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `expect_err()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:27:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:29:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `unwrap()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:35:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:37:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:35:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:37:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:36:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:38:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `expect()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:36:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:38:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_err()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:37:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:39:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_err()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:37:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:39:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect_err()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:38:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:40:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).expect_err("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `expect_err()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:38:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:40:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).expect_err("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:41:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:43:17 | LL | let _val2 = val.unwrap(); | ^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:40:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:42:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:42:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:44:17 | LL | let _val2 = val.expect("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `expect()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:40:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:42:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_err()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:43:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:45:17 | LL | let _val2 = val.unwrap_err(); | ^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_err()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:40:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:42:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect_err()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:44:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:46:17 | LL | let _val2 = val.expect_err("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `expect_err()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:40:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:42:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_err()` on `Err` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:49:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:51:17 | LL | let _val2 = val.unwrap_err(); | ^^^^^^^^^^^^^^^^ | help: remove the `Err` and `unwrap_err()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:48:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:50:15 | LL | let val = Err::<(), _>(1); | ^^^^^^^^^^^^^^^ error: used `expect_err()` on `Err` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:50:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:52:17 | LL | let _val2 = val.expect_err("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `expect_err()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:48:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:50:15 | LL | let val = Err::<(), _>(1); | ^^^^^^^^^^^^^^^ error: used `unwrap()` on `Err` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:51:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:53:17 | LL | let _val2 = val.unwrap(); | ^^^^^^^^^^^^ | help: remove the `Err` and `unwrap()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:48:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:50:15 | LL | let val = Err::<(), _>(1); | ^^^^^^^^^^^^^^^ error: used `expect()` on `Err` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:52:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:54:17 | LL | let _val2 = val.expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `expect()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:48:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:50:15 | LL | let val = Err::<(), _>(1); | ^^^^^^^^^^^^^^^ error: used `unwrap_err()` on `Err` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:56:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:58:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `unwrap_err()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:56:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:58:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap_err(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect_err()` on `Err` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:57:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:59:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect_err("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `expect_err()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:57:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:59:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect_err("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap()` on `Err` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:58:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:60:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `unwrap()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:58:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:60:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect()` on `Err` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:59:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:61:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `expect()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:59:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:61:16 | LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_err()` on `Err` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:62:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:64:17 | LL | let _val2 = val.unwrap_err(); | ^^^^^^^^^^^^^^^^ | help: remove the `Err` and `unwrap_err()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:61:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:63:15 | LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect_err()` on `Err` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:63:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:65:17 | LL | let _val2 = val.expect_err("this never happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `expect_err()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:61:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:63:15 | LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap()` on `Err` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:64:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:66:17 | LL | let _val2 = val.unwrap(); | ^^^^^^^^^^^^ | help: remove the `Err` and `unwrap()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:61:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:63:15 | LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `expect()` on `Err` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:65:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:67:17 | LL | let _val2 = val.expect("this always happens"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Err` and `expect()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:61:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:63:15 | LL | let val = Err::<(), usize>([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or()` on `Some` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:70:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:72:17 | LL | let _val2 = val.unwrap_or(2); | ^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:69:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:71:15 | LL | let val = Some(1); | ^^^^^^^ error: used `unwrap_or_default()` on `Some` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:71:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:73:17 | LL | let _val2 = val.unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or_default()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:69:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:71:15 | LL | let val = Some(1); | ^^^^^^^ error: used `unwrap_or_else()` on `Some` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:72:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:74:17 | LL | let _val2 = val.unwrap_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or_else()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:69:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:71:15 | LL | let val = Some(1); | ^^^^^^^ error: used `unwrap_or()` on `Some` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:76:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:78:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:76:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:78:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_default()` on `Some` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:77:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:79:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or_default()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:77:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:79:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_else()` on `Some` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:78:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:80:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or_else()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:78:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:80:16 | LL | let _val = Some::([1, 2, 3].iter().sum()).unwrap_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or()` on `Some` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:81:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:83:17 | LL | let _val2 = val.unwrap_or(2); | ^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:80:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:82:15 | LL | let val = Some::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_default()` on `Some` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:82:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:84:17 | LL | let _val2 = val.unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or_default()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:80:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:82:15 | LL | let val = Some::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_else()` on `Some` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:83:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:85:17 | LL | let _val2 = val.unwrap_or_else(|| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Some` and `unwrap_or_else()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:80:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:82:15 | LL | let val = Some::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:88:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:90:17 | LL | let _val2 = val.unwrap_or(2); | ^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:87:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:89:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `unwrap_or_default()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:89:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:91:17 | LL | let _val2 = val.unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or_default()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:87:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:89:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `unwrap_or_else()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:90:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:92:17 | LL | let _val2 = val.unwrap_or_else(|_| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or_else()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:87:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:89:15 | LL | let val = Ok::<_, ()>(1); | ^^^^^^^^^^^^^^ error: used `unwrap_or()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:94:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:96:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:94:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:96:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or(2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_default()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:95:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:97:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or_default()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:95:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:97:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_else()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:96:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:98:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or_else()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:96:16 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:98:16 | LL | let _val = Ok::([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:99:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:101:17 | LL | let _val2 = val.unwrap_or(2); | ^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:98:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:100:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_default()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:100:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:102:17 | LL | let _val2 = val.unwrap_or_default(); | ^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or_default()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:98:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:100:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: used `unwrap_or_else()` on `Ok` value - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:101:17 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:103:17 | LL | let _val2 = val.unwrap_or_else(|_| 2); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove the `Ok` and `unwrap_or_else()` - --> $DIR/unnecessary_literal_unwrap_unfixable.rs:98:15 + --> $DIR/unnecessary_literal_unwrap_unfixable.rs:100:15 | LL | let val = Ok::([1, 2, 3].iter().sum()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 50 previous errors +error: aborting due to 52 previous errors diff --git a/src/tools/clippy/tests/ui/useless_conversion.fixed b/src/tools/clippy/tests/ui/useless_conversion.fixed index 5d2c5b11658e2..53d8a5a9ff18b 100644 --- a/src/tools/clippy/tests/ui/useless_conversion.fixed +++ b/src/tools/clippy/tests/ui/useless_conversion.fixed @@ -155,6 +155,20 @@ fn main() { let _ = vec![s4, s4, s4].into_iter(); } +#[allow(dead_code)] +fn issue11065_fp() { + use std::option::IntoIter; + fn takes_into_iter(_: impl IntoIterator) {} + + macro_rules! x { + ($e:expr) => { + takes_into_iter($e); + let _: IntoIter = $e; // removing `.into_iter()` leads to a type error here + }; + } + x!(Some(5).into_iter()); +} + #[allow(dead_code)] fn explicit_into_iter_fn_arg() { fn a(_: T) {} diff --git a/src/tools/clippy/tests/ui/useless_conversion.rs b/src/tools/clippy/tests/ui/useless_conversion.rs index 03a3e3f95ba42..51ba498733965 100644 --- a/src/tools/clippy/tests/ui/useless_conversion.rs +++ b/src/tools/clippy/tests/ui/useless_conversion.rs @@ -155,6 +155,20 @@ fn main() { let _ = vec![s4, s4, s4].into_iter().into_iter(); } +#[allow(dead_code)] +fn issue11065_fp() { + use std::option::IntoIter; + fn takes_into_iter(_: impl IntoIterator) {} + + macro_rules! x { + ($e:expr) => { + takes_into_iter($e); + let _: IntoIter = $e; // removing `.into_iter()` leads to a type error here + }; + } + x!(Some(5).into_iter()); +} + #[allow(dead_code)] fn explicit_into_iter_fn_arg() { fn a(_: T) {} diff --git a/src/tools/clippy/tests/ui/useless_conversion.stderr b/src/tools/clippy/tests/ui/useless_conversion.stderr index 4957f73a469a6..6f7dc01d2cd27 100644 --- a/src/tools/clippy/tests/ui/useless_conversion.stderr +++ b/src/tools/clippy/tests/ui/useless_conversion.stderr @@ -119,61 +119,61 @@ LL | let _ = vec![s4, s4, s4].into_iter().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![s4, s4, s4].into_iter()` error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> $DIR/useless_conversion.rs:171:7 + --> $DIR/useless_conversion.rs:185:7 | LL | b(vec![1, 2].into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> $DIR/useless_conversion.rs:161:13 + --> $DIR/useless_conversion.rs:175:13 | LL | fn b>(_: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> $DIR/useless_conversion.rs:172:7 + --> $DIR/useless_conversion.rs:186:7 | LL | c(vec![1, 2].into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> $DIR/useless_conversion.rs:162:18 + --> $DIR/useless_conversion.rs:176:18 | LL | fn c(_: impl IntoIterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> $DIR/useless_conversion.rs:173:7 + --> $DIR/useless_conversion.rs:187:7 | LL | d(vec![1, 2].into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> $DIR/useless_conversion.rs:165:12 + --> $DIR/useless_conversion.rs:179:12 | LL | T: IntoIterator, | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> $DIR/useless_conversion.rs:176:7 + --> $DIR/useless_conversion.rs:190:7 | LL | b(vec![1, 2].into_iter().into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`s: `vec![1, 2]` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> $DIR/useless_conversion.rs:161:13 + --> $DIR/useless_conversion.rs:175:13 | LL | fn b>(_: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit call to `.into_iter()` in function argument accepting `IntoIterator` - --> $DIR/useless_conversion.rs:177:7 + --> $DIR/useless_conversion.rs:191:7 | LL | b(vec![1, 2].into_iter().into_iter().into_iter()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`s: `vec![1, 2]` | note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()` - --> $DIR/useless_conversion.rs:161:13 + --> $DIR/useless_conversion.rs:175:13 | LL | fn b>(_: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^