mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-26 14:40:32 +00:00
Merge unwrap_or_else_default.rs
into or_fun_call.rs
This commit is contained in:
parent
0b63e95dce
commit
84c411272d
9 changed files with 343 additions and 191 deletions
|
@ -103,7 +103,6 @@ mod unnecessary_lazy_eval;
|
|||
mod unnecessary_literal_unwrap;
|
||||
mod unnecessary_sort_by;
|
||||
mod unnecessary_to_owned;
|
||||
mod unwrap_or_else_default;
|
||||
mod unwrap_used;
|
||||
mod useless_asref;
|
||||
mod utils;
|
||||
|
@ -476,29 +475,40 @@ declare_clippy_lint! {
|
|||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for usage of `_.unwrap_or_else(Default::default)` on `Option` and
|
||||
/// `Result` values.
|
||||
/// Checks for usages of the following functions with an argument that constructs a default value
|
||||
/// (e.g., `Default::default` or `String::new`):
|
||||
/// - `unwrap_or`
|
||||
/// - `unwrap_or_else`
|
||||
/// - `or_insert`
|
||||
/// - `or_insert_with`
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// Readability, these can be written as `_.unwrap_or_default`, which is
|
||||
/// simpler and more concise.
|
||||
/// Readability. Using `unwrap_or_default` in place of `unwrap_or`/`unwrap_or_else`, or `or_default`
|
||||
/// in place of `or_insert`/`or_insert_with`, is simpler and more concise.
|
||||
///
|
||||
/// ### Known problems
|
||||
/// In some cases, the argument of `unwrap_or`, etc. is needed for type inference. The lint uses a
|
||||
/// heuristic to try to identify such cases. However, the heuristic can produce false negatives.
|
||||
///
|
||||
/// ### Examples
|
||||
/// ```rust
|
||||
/// # let x = Some(1);
|
||||
/// x.unwrap_or_else(Default::default);
|
||||
/// x.unwrap_or_else(u32::default);
|
||||
/// # let mut map = std::collections::HashMap::<u64, String>::new();
|
||||
/// x.unwrap_or(Default::default());
|
||||
/// map.entry(42).or_insert_with(String::new);
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```rust
|
||||
/// # let x = Some(1);
|
||||
/// # let mut map = std::collections::HashMap::<u64, String>::new();
|
||||
/// x.unwrap_or_default();
|
||||
/// map.entry(42).or_default();
|
||||
/// ```
|
||||
#[clippy::version = "1.56.0"]
|
||||
pub UNWRAP_OR_ELSE_DEFAULT,
|
||||
style,
|
||||
"using `.unwrap_or_else(Default::default)`, which is more succinctly expressed as `.unwrap_or_default()`"
|
||||
"using `.unwrap_or`, etc. with an argument that constructs a default value"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -3756,8 +3766,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
|||
then {
|
||||
let first_arg_span = first_arg_ty.span;
|
||||
let first_arg_ty = hir_ty_to_ty(cx.tcx, first_arg_ty);
|
||||
let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id())
|
||||
.self_ty();
|
||||
let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id()).self_ty();
|
||||
wrong_self_convention::check(
|
||||
cx,
|
||||
item.ident.name.as_str(),
|
||||
|
@ -3774,8 +3783,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
|||
if item.ident.name == sym::new;
|
||||
if let TraitItemKind::Fn(_, _) = item.kind;
|
||||
let ret_ty = return_ty(cx, item.owner_id);
|
||||
let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id())
|
||||
.self_ty();
|
||||
let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id()).self_ty();
|
||||
if !ret_ty.contains(self_ty);
|
||||
|
||||
then {
|
||||
|
@ -4134,7 +4142,6 @@ impl Methods {
|
|||
Some(("map", recv, [map_arg], _, _))
|
||||
if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, &self.msrv) => {},
|
||||
_ => {
|
||||
unwrap_or_else_default::check(cx, expr, recv, u_arg);
|
||||
unnecessary_lazy_eval::check(cx, expr, recv, u_arg, "unwrap_or");
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::eager_or_lazy::switch_to_lazy_eval;
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
|
||||
use clippy_utils::{contains_return, is_trait_item, last_path_segment};
|
||||
use clippy_utils::ty::{expr_type_is_certain, implements_trait, is_type_diagnostic_item};
|
||||
use clippy_utils::{contains_return, is_default_equivalent, is_default_equivalent_call, last_path_segment};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty;
|
||||
use rustc_span::source_map::Span;
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use rustc_span::symbol::{self, sym, Symbol};
|
||||
use {rustc_ast as ast, rustc_hir as hir};
|
||||
|
||||
use super::OR_FUN_CALL;
|
||||
use super::{OR_FUN_CALL, UNWRAP_OR_ELSE_DEFAULT};
|
||||
|
||||
/// Checks for the `OR_FUN_CALL` lint.
|
||||
#[allow(clippy::too_many_lines)]
|
||||
|
@ -24,44 +25,64 @@ pub(super) fn check<'tcx>(
|
|||
) {
|
||||
/// Checks for `unwrap_or(T::new())`, `unwrap_or(T::default())`,
|
||||
/// `or_insert(T::new())` or `or_insert(T::default())`.
|
||||
/// Similarly checks for `unwrap_or_else(T::new)`, `unwrap_or_else(T::default)`,
|
||||
/// `or_insert_with(T::new)` or `or_insert_with(T::default)`.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn check_unwrap_or_default(
|
||||
cx: &LateContext<'_>,
|
||||
name: &str,
|
||||
receiver: &hir::Expr<'_>,
|
||||
fun: &hir::Expr<'_>,
|
||||
arg: &hir::Expr<'_>,
|
||||
or_has_args: bool,
|
||||
call_expr: Option<&hir::Expr<'_>>,
|
||||
span: Span,
|
||||
method_span: Span,
|
||||
) -> bool {
|
||||
let is_default_default = || is_trait_item(cx, fun, sym::Default);
|
||||
if !expr_type_is_certain(cx, receiver) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let implements_default = |arg, default_trait_id| {
|
||||
let arg_ty = cx.typeck_results().expr_ty(arg);
|
||||
implements_trait(cx, arg_ty, default_trait_id, &[])
|
||||
let is_new = |fun: &hir::Expr<'_>| {
|
||||
if let hir::ExprKind::Path(ref qpath) = fun.kind {
|
||||
let path = last_path_segment(qpath).ident.name;
|
||||
matches!(path, sym::new)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
let output_type_implements_default = |fun| {
|
||||
let fun_ty = cx.typeck_results().expr_ty(fun);
|
||||
if let ty::FnDef(def_id, substs) = fun_ty.kind() {
|
||||
let output_ty = cx.tcx.fn_sig(def_id).subst(cx.tcx, substs).skip_binder().output();
|
||||
cx.tcx
|
||||
.get_diagnostic_item(sym::Default)
|
||||
.map_or(false, |default_trait_id| {
|
||||
implements_trait(cx, output_ty, default_trait_id, substs)
|
||||
})
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
if_chain! {
|
||||
if !or_has_args;
|
||||
if let Some(sugg) = match name {
|
||||
"unwrap_or" => Some("unwrap_or_default"),
|
||||
"or_insert" => Some("or_default"),
|
||||
if let Some(sugg) = match (name, call_expr.is_some()) {
|
||||
("unwrap_or", true) | ("unwrap_or_else", false) => Some("unwrap_or_default"),
|
||||
("or_insert", true) | ("or_insert_with", false) => Some("or_default"),
|
||||
_ => None,
|
||||
};
|
||||
if let hir::ExprKind::Path(ref qpath) = fun.kind;
|
||||
if let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default);
|
||||
let path = last_path_segment(qpath).ident.name;
|
||||
// needs to target Default::default in particular or be *::new and have a Default impl
|
||||
// available
|
||||
if (matches!(path, kw::Default) && is_default_default())
|
||||
|| (matches!(path, sym::new) && implements_default(arg, default_trait_id));
|
||||
|
||||
if (is_new(fun) && output_type_implements_default(fun))
|
||||
|| match call_expr {
|
||||
Some(call_expr) => is_default_equivalent(cx, call_expr),
|
||||
None => is_default_equivalent_call(cx, fun) || closure_body_returns_empty_to_string(cx, fun),
|
||||
};
|
||||
then {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
OR_FUN_CALL,
|
||||
UNWRAP_OR_ELSE_DEFAULT,
|
||||
method_span.with_hi(span.hi()),
|
||||
&format!("use of `{name}` followed by a call to `{path}`"),
|
||||
&format!("use of `{name}` to construct default value"),
|
||||
"try",
|
||||
format!("{sugg}()"),
|
||||
Applicability::MachineApplicable,
|
||||
|
@ -168,11 +189,16 @@ pub(super) fn check<'tcx>(
|
|||
match inner_arg.kind {
|
||||
hir::ExprKind::Call(fun, or_args) => {
|
||||
let or_has_args = !or_args.is_empty();
|
||||
if !check_unwrap_or_default(cx, name, fun, arg, or_has_args, expr.span, method_span) {
|
||||
if or_has_args
|
||||
|| !check_unwrap_or_default(cx, name, receiver, fun, Some(inner_arg), expr.span, method_span)
|
||||
{
|
||||
let fun_span = if or_has_args { None } else { Some(fun.span) };
|
||||
check_general_case(cx, name, method_span, receiver, arg, None, expr.span, fun_span);
|
||||
}
|
||||
},
|
||||
hir::ExprKind::Path(..) | hir::ExprKind::Closure(..) => {
|
||||
check_unwrap_or_default(cx, name, receiver, inner_arg, None, expr.span, method_span);
|
||||
},
|
||||
hir::ExprKind::Index(..) | hir::ExprKind::MethodCall(..) => {
|
||||
check_general_case(cx, name, method_span, receiver, arg, None, expr.span, None);
|
||||
},
|
||||
|
@ -189,3 +215,22 @@ pub(super) fn check<'tcx>(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn closure_body_returns_empty_to_string(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> bool {
|
||||
if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = e.kind {
|
||||
let body = cx.tcx.hir().body(body);
|
||||
|
||||
if body.params.is_empty()
|
||||
&& let hir::Expr{ kind, .. } = &body.value
|
||||
&& let hir::ExprKind::MethodCall(hir::PathSegment {ident, ..}, self_arg, _, _) = kind
|
||||
&& ident == &symbol::Ident::from_str("to_string")
|
||||
&& let hir::Expr{ kind, .. } = self_arg
|
||||
&& let hir::ExprKind::Lit(lit) = kind
|
||||
&& let ast::LitKind::Str(symbol::kw::Empty, _) = lit.node
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
//! Lint for `some_result_or_option.unwrap_or_else(Default::default)`
|
||||
|
||||
use super::UNWRAP_OR_ELSE_DEFAULT;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::is_default_equivalent_call;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::ty::{expr_type_is_certain, is_type_diagnostic_item};
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::{sym, symbol};
|
||||
|
||||
pub(super) fn check<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
expr: &'tcx hir::Expr<'_>,
|
||||
recv: &'tcx hir::Expr<'_>,
|
||||
u_arg: &'tcx hir::Expr<'_>,
|
||||
) {
|
||||
if !expr_type_is_certain(cx, recv) {
|
||||
return;
|
||||
}
|
||||
|
||||
// something.unwrap_or_else(Default::default)
|
||||
// ^^^^^^^^^- recv ^^^^^^^^^^^^^^^^- u_arg
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- expr
|
||||
let recv_ty = cx.typeck_results().expr_ty(recv);
|
||||
let is_option = is_type_diagnostic_item(cx, recv_ty, sym::Option);
|
||||
let is_result = is_type_diagnostic_item(cx, recv_ty, sym::Result);
|
||||
|
||||
if_chain! {
|
||||
if is_option || is_result;
|
||||
if closure_body_returns_empty_to_string(cx, u_arg) || is_default_equivalent_call(cx, u_arg);
|
||||
then {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
UNWRAP_OR_ELSE_DEFAULT,
|
||||
expr.span,
|
||||
"use of `.unwrap_or_else(..)` to construct default value",
|
||||
"try",
|
||||
format!(
|
||||
"{}.unwrap_or_default()",
|
||||
snippet_with_applicability(cx, recv.span, "..", &mut applicability)
|
||||
),
|
||||
applicability,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn closure_body_returns_empty_to_string(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> bool {
|
||||
if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = e.kind {
|
||||
let body = cx.tcx.hir().body(body);
|
||||
|
||||
if body.params.is_empty()
|
||||
&& let hir::Expr{ kind, .. } = &body.value
|
||||
&& let hir::ExprKind::MethodCall(hir::PathSegment {ident, ..}, self_arg, _, _) = kind
|
||||
&& ident == &symbol::Ident::from_str("to_string")
|
||||
&& let hir::Expr{ kind, .. } = self_arg
|
||||
&& let hir::ExprKind::Lit(lit) = kind
|
||||
&& let LitKind::Str(symbol::kw::Empty, _) = lit.node
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
|
@ -190,7 +190,7 @@ mod issue8239 {
|
|||
acc.push_str(&f);
|
||||
acc
|
||||
})
|
||||
.unwrap_or_default();
|
||||
.unwrap_or(String::new());
|
||||
}
|
||||
|
||||
fn more_to_max_suggestion_highest_lines_1() {
|
||||
|
@ -203,7 +203,7 @@ mod issue8239 {
|
|||
acc.push_str(&f);
|
||||
acc
|
||||
})
|
||||
.unwrap_or_default();
|
||||
.unwrap_or(String::new());
|
||||
}
|
||||
|
||||
fn equal_to_max_suggestion_highest_lines() {
|
||||
|
@ -215,7 +215,7 @@ mod issue8239 {
|
|||
acc.push_str(&f);
|
||||
acc
|
||||
})
|
||||
.unwrap_or_default();
|
||||
.unwrap_or(String::new());
|
||||
}
|
||||
|
||||
fn less_than_max_suggestion_highest_lines() {
|
||||
|
@ -226,7 +226,7 @@ mod issue8239 {
|
|||
acc.push_str(&f);
|
||||
acc
|
||||
})
|
||||
.unwrap_or_default();
|
||||
.unwrap_or(String::new());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -257,4 +257,59 @@ mod issue8993 {
|
|||
}
|
||||
}
|
||||
|
||||
mod lazy {
|
||||
use super::*;
|
||||
|
||||
fn foo() {
|
||||
struct Foo;
|
||||
|
||||
impl Foo {
|
||||
fn new() -> Foo {
|
||||
Foo
|
||||
}
|
||||
}
|
||||
|
||||
struct FakeDefault;
|
||||
impl FakeDefault {
|
||||
fn default() -> Self {
|
||||
FakeDefault
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FakeDefault {
|
||||
fn default() -> Self {
|
||||
FakeDefault
|
||||
}
|
||||
}
|
||||
|
||||
let with_new = Some(vec![1]);
|
||||
with_new.unwrap_or_default();
|
||||
|
||||
let with_default_trait = Some(1);
|
||||
with_default_trait.unwrap_or_default();
|
||||
|
||||
let with_default_type = Some(1);
|
||||
with_default_type.unwrap_or_default();
|
||||
|
||||
let real_default = None::<FakeDefault>;
|
||||
real_default.unwrap_or_default();
|
||||
|
||||
let mut map = HashMap::<u64, String>::new();
|
||||
map.entry(42).or_default();
|
||||
|
||||
let mut btree = BTreeMap::<u64, String>::new();
|
||||
btree.entry(42).or_default();
|
||||
|
||||
let stringy = Some(String::new());
|
||||
let _ = stringy.unwrap_or_default();
|
||||
|
||||
// negative tests
|
||||
let self_default = None::<FakeDefault>;
|
||||
self_default.unwrap_or_else(<FakeDefault>::default);
|
||||
|
||||
let without_default = Some(Foo);
|
||||
without_default.unwrap_or_else(Foo::new);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -257,4 +257,59 @@ mod issue8993 {
|
|||
}
|
||||
}
|
||||
|
||||
mod lazy {
|
||||
use super::*;
|
||||
|
||||
fn foo() {
|
||||
struct Foo;
|
||||
|
||||
impl Foo {
|
||||
fn new() -> Foo {
|
||||
Foo
|
||||
}
|
||||
}
|
||||
|
||||
struct FakeDefault;
|
||||
impl FakeDefault {
|
||||
fn default() -> Self {
|
||||
FakeDefault
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FakeDefault {
|
||||
fn default() -> Self {
|
||||
FakeDefault
|
||||
}
|
||||
}
|
||||
|
||||
let with_new = Some(vec![1]);
|
||||
with_new.unwrap_or_else(Vec::new);
|
||||
|
||||
let with_default_trait = Some(1);
|
||||
with_default_trait.unwrap_or_else(Default::default);
|
||||
|
||||
let with_default_type = Some(1);
|
||||
with_default_type.unwrap_or_else(u64::default);
|
||||
|
||||
let real_default = None::<FakeDefault>;
|
||||
real_default.unwrap_or_else(<FakeDefault as Default>::default);
|
||||
|
||||
let mut map = HashMap::<u64, String>::new();
|
||||
map.entry(42).or_insert_with(String::new);
|
||||
|
||||
let mut btree = BTreeMap::<u64, String>::new();
|
||||
btree.entry(42).or_insert_with(String::new);
|
||||
|
||||
let stringy = Some(String::new());
|
||||
let _ = stringy.unwrap_or_else(String::new);
|
||||
|
||||
// negative tests
|
||||
let self_default = None::<FakeDefault>;
|
||||
self_default.unwrap_or_else(<FakeDefault>::default);
|
||||
|
||||
let without_default = Some(Foo);
|
||||
without_default.unwrap_or_else(Foo::new);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -6,11 +6,13 @@ LL | with_constructor.unwrap_or(make());
|
|||
|
|
||||
= note: `-D clippy::or-fun-call` implied by `-D warnings`
|
||||
|
||||
error: use of `unwrap_or` followed by a call to `new`
|
||||
error: use of `unwrap_or` to construct default value
|
||||
--> $DIR/or_fun_call.rs:56:14
|
||||
|
|
||||
LL | with_new.unwrap_or(Vec::new());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
|
||||
= note: `-D clippy::unwrap-or-else-default` implied by `-D warnings`
|
||||
|
||||
error: use of `unwrap_or` followed by a function call
|
||||
--> $DIR/or_fun_call.rs:59:21
|
||||
|
@ -30,13 +32,13 @@ error: use of `unwrap_or` followed by a function call
|
|||
LL | with_err_args.unwrap_or(Vec::with_capacity(12));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| Vec::with_capacity(12))`
|
||||
|
||||
error: use of `unwrap_or` followed by a call to `default`
|
||||
error: use of `unwrap_or` to construct default value
|
||||
--> $DIR/or_fun_call.rs:68:24
|
||||
|
|
||||
LL | with_default_trait.unwrap_or(Default::default());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `unwrap_or` followed by a call to `default`
|
||||
error: use of `unwrap_or` to construct default value
|
||||
--> $DIR/or_fun_call.rs:71:23
|
||||
|
|
||||
LL | with_default_type.unwrap_or(u64::default());
|
||||
|
@ -48,13 +50,13 @@ error: use of `unwrap_or` followed by a function call
|
|||
LL | self_default.unwrap_or(<FakeDefault>::default());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(<FakeDefault>::default)`
|
||||
|
||||
error: use of `unwrap_or` followed by a call to `default`
|
||||
error: use of `unwrap_or` to construct default value
|
||||
--> $DIR/or_fun_call.rs:77:18
|
||||
|
|
||||
LL | real_default.unwrap_or(<FakeDefault as Default>::default());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `unwrap_or` followed by a call to `new`
|
||||
error: use of `unwrap_or` to construct default value
|
||||
--> $DIR/or_fun_call.rs:80:14
|
||||
|
|
||||
LL | with_vec.unwrap_or(vec![]);
|
||||
|
@ -66,31 +68,31 @@ error: use of `unwrap_or` followed by a function call
|
|||
LL | without_default.unwrap_or(Foo::new());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(Foo::new)`
|
||||
|
||||
error: use of `or_insert` followed by a call to `new`
|
||||
error: use of `or_insert` to construct default value
|
||||
--> $DIR/or_fun_call.rs:86:19
|
||||
|
|
||||
LL | map.entry(42).or_insert(String::new());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`
|
||||
|
||||
error: use of `or_insert` followed by a call to `new`
|
||||
error: use of `or_insert` to construct default value
|
||||
--> $DIR/or_fun_call.rs:89:23
|
||||
|
|
||||
LL | map_vec.entry(42).or_insert(vec![]);
|
||||
| ^^^^^^^^^^^^^^^^^ help: try: `or_default()`
|
||||
|
||||
error: use of `or_insert` followed by a call to `new`
|
||||
error: use of `or_insert` to construct default value
|
||||
--> $DIR/or_fun_call.rs:92:21
|
||||
|
|
||||
LL | btree.entry(42).or_insert(String::new());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`
|
||||
|
||||
error: use of `or_insert` followed by a call to `new`
|
||||
error: use of `or_insert` to construct default value
|
||||
--> $DIR/or_fun_call.rs:95:25
|
||||
|
|
||||
LL | btree_vec.entry(42).or_insert(vec![]);
|
||||
| ^^^^^^^^^^^^^^^^^ help: try: `or_default()`
|
||||
|
||||
error: use of `unwrap_or` followed by a call to `new`
|
||||
error: use of `unwrap_or` to construct default value
|
||||
--> $DIR/or_fun_call.rs:98:21
|
||||
|
|
||||
LL | let _ = stringy.unwrap_or(String::new());
|
||||
|
@ -132,30 +134,6 @@ error: use of `unwrap_or` followed by a function call
|
|||
LL | None.unwrap_or( unsafe { ptr_to_ref(s) } );
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| unsafe { ptr_to_ref(s) })`
|
||||
|
||||
error: use of `unwrap_or` followed by a call to `new`
|
||||
--> $DIR/or_fun_call.rs:193:14
|
||||
|
|
||||
LL | .unwrap_or(String::new());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `unwrap_or` followed by a call to `new`
|
||||
--> $DIR/or_fun_call.rs:206:14
|
||||
|
|
||||
LL | .unwrap_or(String::new());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `unwrap_or` followed by a call to `new`
|
||||
--> $DIR/or_fun_call.rs:218:14
|
||||
|
|
||||
LL | .unwrap_or(String::new());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `unwrap_or` followed by a call to `new`
|
||||
--> $DIR/or_fun_call.rs:229:10
|
||||
|
|
||||
LL | .unwrap_or(String::new());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `map_or` followed by a function call
|
||||
--> $DIR/or_fun_call.rs:254:25
|
||||
|
|
||||
|
@ -168,5 +146,47 @@ error: use of `map_or` followed by a function call
|
|||
LL | let _ = Some(4).map_or(g(), f);
|
||||
| ^^^^^^^^^^^^^^ help: try: `map_or_else(g, f)`
|
||||
|
||||
error: aborting due to 28 previous errors
|
||||
error: use of `unwrap_or_else` to construct default value
|
||||
--> $DIR/or_fun_call.rs:286:18
|
||||
|
|
||||
LL | with_new.unwrap_or_else(Vec::new);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `unwrap_or_else` to construct default value
|
||||
--> $DIR/or_fun_call.rs:289:28
|
||||
|
|
||||
LL | with_default_trait.unwrap_or_else(Default::default);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `unwrap_or_else` to construct default value
|
||||
--> $DIR/or_fun_call.rs:292:27
|
||||
|
|
||||
LL | with_default_type.unwrap_or_else(u64::default);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `unwrap_or_else` to construct default value
|
||||
--> $DIR/or_fun_call.rs:295:22
|
||||
|
|
||||
LL | real_default.unwrap_or_else(<FakeDefault as Default>::default);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `or_insert_with` to construct default value
|
||||
--> $DIR/or_fun_call.rs:298:23
|
||||
|
|
||||
LL | map.entry(42).or_insert_with(String::new);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`
|
||||
|
||||
error: use of `or_insert_with` to construct default value
|
||||
--> $DIR/or_fun_call.rs:301:25
|
||||
|
|
||||
LL | btree.entry(42).or_insert_with(String::new);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`
|
||||
|
||||
error: use of `unwrap_or_else` to construct default value
|
||||
--> $DIR/or_fun_call.rs:304:25
|
||||
|
|
||||
LL | let _ = stringy.unwrap_or_else(String::new);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: aborting due to 31 previous errors
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#![allow(dead_code)]
|
||||
#![allow(clippy::unnecessary_wraps, clippy::unnecessary_literal_unwrap)]
|
||||
|
||||
/// Checks implementation of the `UNWRAP_OR_ELSE_DEFAULT` lint.
|
||||
/// Checks implementation of the `UNWRAP_OR_DEFAULT` lint.
|
||||
fn unwrap_or_else_default() {
|
||||
struct Foo;
|
||||
|
||||
|
@ -111,4 +111,21 @@ fn type_certainty(option: Option<Vec<u64>>) {
|
|||
option.unwrap_or_else(Vec::new).push(1);
|
||||
}
|
||||
|
||||
fn method_call_with_deref() {
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
|
||||
let cell = RefCell::new(HashMap::<u64, HashMap<u64, String>>::new());
|
||||
|
||||
let mut outer_map = cell.borrow_mut();
|
||||
|
||||
#[allow(unused_assignments)]
|
||||
let mut option = None;
|
||||
option = Some(0);
|
||||
|
||||
let inner_map = outer_map.get_mut(&option.unwrap()).unwrap();
|
||||
|
||||
let _ = inner_map.entry(0).or_default();
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#![allow(dead_code)]
|
||||
#![allow(clippy::unnecessary_wraps, clippy::unnecessary_literal_unwrap)]
|
||||
|
||||
/// Checks implementation of the `UNWRAP_OR_ELSE_DEFAULT` lint.
|
||||
/// Checks implementation of the `UNWRAP_OR_DEFAULT` lint.
|
||||
fn unwrap_or_else_default() {
|
||||
struct Foo;
|
||||
|
||||
|
@ -111,4 +111,21 @@ fn type_certainty(option: Option<Vec<u64>>) {
|
|||
option.unwrap_or_else(Vec::new).push(1);
|
||||
}
|
||||
|
||||
fn method_call_with_deref() {
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
|
||||
let cell = RefCell::new(HashMap::<u64, HashMap<u64, String>>::new());
|
||||
|
||||
let mut outer_map = cell.borrow_mut();
|
||||
|
||||
#[allow(unused_assignments)]
|
||||
let mut option = None;
|
||||
option = Some(0);
|
||||
|
||||
let inner_map = outer_map.get_mut(&option.unwrap()).unwrap();
|
||||
|
||||
let _ = inner_map.entry(0).or_insert_with(Default::default);
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,88 +1,94 @@
|
|||
error: use of `.unwrap_or_else(..)` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:48:5
|
||||
error: use of `unwrap_or_else` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:48:14
|
||||
|
|
||||
LL | with_new.unwrap_or_else(Vec::new);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `with_new.unwrap_or_default()`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
|
||||
= note: `-D clippy::unwrap-or-else-default` implied by `-D warnings`
|
||||
|
||||
error: use of `.unwrap_or_else(..)` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:62:5
|
||||
error: use of `unwrap_or_else` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:62:23
|
||||
|
|
||||
LL | with_real_default.unwrap_or_else(<HasDefaultAndDuplicate as Default>::default);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `with_real_default.unwrap_or_default()`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `.unwrap_or_else(..)` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:65:5
|
||||
error: use of `unwrap_or_else` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:65:24
|
||||
|
|
||||
LL | with_default_trait.unwrap_or_else(Default::default);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `with_default_trait.unwrap_or_default()`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `.unwrap_or_else(..)` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:68:5
|
||||
error: use of `unwrap_or_else` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:68:23
|
||||
|
|
||||
LL | with_default_type.unwrap_or_else(u64::default);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `with_default_type.unwrap_or_default()`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `.unwrap_or_else(..)` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:71:5
|
||||
error: use of `unwrap_or_else` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:71:23
|
||||
|
|
||||
LL | with_default_type.unwrap_or_else(Vec::new);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `with_default_type.unwrap_or_default()`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `.unwrap_or_else(..)` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:74:5
|
||||
error: use of `unwrap_or_else` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:74:18
|
||||
|
|
||||
LL | empty_string.unwrap_or_else(|| "".to_string());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `empty_string.unwrap_or_default()`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `.unwrap_or_else(..)` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:78:5
|
||||
error: use of `unwrap_or_else` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:78:12
|
||||
|
|
||||
LL | option.unwrap_or_else(Vec::new).push(1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `option.unwrap_or_default()`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `.unwrap_or_else(..)` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:81:5
|
||||
error: use of `unwrap_or_else` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:81:12
|
||||
|
|
||||
LL | option.unwrap_or_else(Vec::new).push(1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `option.unwrap_or_default()`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `.unwrap_or_else(..)` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:84:5
|
||||
error: use of `unwrap_or_else` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:84:12
|
||||
|
|
||||
LL | option.unwrap_or_else(Vec::new).push(1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `option.unwrap_or_default()`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `.unwrap_or_else(..)` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:87:5
|
||||
error: use of `unwrap_or_else` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:87:12
|
||||
|
|
||||
LL | option.unwrap_or_else(Vec::new).push(1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `option.unwrap_or_default()`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `.unwrap_or_else(..)` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:90:5
|
||||
error: use of `unwrap_or_else` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:90:12
|
||||
|
|
||||
LL | option.unwrap_or_else(Vec::new).push(1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `option.unwrap_or_default()`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `.unwrap_or_else(..)` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:93:5
|
||||
error: use of `unwrap_or_else` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:93:12
|
||||
|
|
||||
LL | option.unwrap_or_else(Vec::new).push(1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `option.unwrap_or_default()`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `.unwrap_or_else(..)` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:96:5
|
||||
error: use of `unwrap_or_else` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:96:12
|
||||
|
|
||||
LL | option.unwrap_or_else(Vec::new).push(1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `option.unwrap_or_default()`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: use of `.unwrap_or_else(..)` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:99:5
|
||||
error: use of `unwrap_or_else` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:99:12
|
||||
|
|
||||
LL | option.unwrap_or_else(Vec::new).push(1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `option.unwrap_or_default()`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
||||
|
||||
error: aborting due to 14 previous errors
|
||||
error: use of `or_insert_with` to construct default value
|
||||
--> $DIR/unwrap_or_else_default.rs:128:32
|
||||
|
|
||||
LL | let _ = inner_map.entry(0).or_insert_with(Default::default);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`
|
||||
|
||||
error: aborting due to 15 previous errors
|
||||
|
||||
|
|
Loading…
Reference in a new issue