Merge unwrap_or_else_default.rs into or_fun_call.rs

This commit is contained in:
Samuel Moelius 2023-07-19 20:05:16 -04:00
parent 0b63e95dce
commit 84c411272d
9 changed files with 343 additions and 191 deletions

View file

@ -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");
},
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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() {}

View file

@ -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() {}

View file

@ -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

View file

@ -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() {}

View file

@ -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() {}

View file

@ -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