|
1 | 1 | use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
|
2 | 2 | use clippy_utils::source::{snippet, snippet_with_applicability};
|
3 |
| -use clippy_utils::{in_macro, is_diag_trait_item, is_lang_ctor, match_def_path, meets_msrv, msrvs, paths}; |
| 3 | +use clippy_utils::{in_macro, is_default_equivalent, is_lang_ctor, match_def_path, meets_msrv, msrvs, paths}; |
4 | 4 | use if_chain::if_chain;
|
5 | 5 | use rustc_errors::Applicability;
|
6 |
| -use rustc_hir::def_id::DefId; |
7 | 6 | use rustc_hir::LangItem::OptionNone;
|
8 | 7 | use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, QPath};
|
9 | 8 | use rustc_lint::{LateContext, LateLintPass, LintContext};
|
@@ -194,64 +193,36 @@ fn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'
|
194 | 193 | }
|
195 | 194 | }
|
196 | 195 |
|
197 |
| -/// Returns true if the `def_id` associated with the `path` is recognized as a "default-equivalent" |
198 |
| -/// constructor from the std library |
199 |
| -fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<'_>) -> bool { |
200 |
| - let std_types_symbols = &[ |
201 |
| - sym::string_type, |
202 |
| - sym::vec_type, |
203 |
| - sym::vecdeque_type, |
204 |
| - sym::LinkedList, |
205 |
| - sym::hashmap_type, |
206 |
| - sym::BTreeMap, |
207 |
| - sym::hashset_type, |
208 |
| - sym::BTreeSet, |
209 |
| - sym::BinaryHeap, |
210 |
| - ]; |
211 |
| - |
212 |
| - if let QPath::TypeRelative(_, method) = path { |
213 |
| - if method.ident.name == sym::new { |
214 |
| - if let Some(impl_did) = cx.tcx.impl_of_method(def_id) { |
215 |
| - if let Some(adt) = cx.tcx.type_of(impl_did).ty_adt_def() { |
216 |
| - return std_types_symbols |
217 |
| - .iter() |
218 |
| - .any(|&symbol| cx.tcx.is_diagnostic_item(symbol, adt.did)); |
219 |
| - } |
220 |
| - } |
| 196 | +fn check_replace_with_default(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) { |
| 197 | + // disable lint for primitives |
| 198 | + if let ExprKind::Lit(_) = src.kind { |
| 199 | + return; |
| 200 | + } |
| 201 | + // disable lint for Option since it is covered in another lint |
| 202 | + if let ExprKind::Path(q) = &src.kind { |
| 203 | + if is_lang_ctor(cx, q, OptionNone) { |
| 204 | + return; |
221 | 205 | }
|
222 | 206 | }
|
223 |
| - false |
224 |
| -} |
| 207 | + if is_default_equivalent(cx, src) && !in_external_macro(cx.tcx.sess, expr_span) { |
| 208 | + span_lint_and_then( |
| 209 | + cx, |
| 210 | + MEM_REPLACE_WITH_DEFAULT, |
| 211 | + expr_span, |
| 212 | + "replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`", |
| 213 | + |diag| { |
| 214 | + if !in_macro(expr_span) { |
| 215 | + let suggestion = format!("std::mem::take({})", snippet(cx, dest.span, "")); |
225 | 216 |
|
226 |
| -fn check_replace_with_default(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) { |
227 |
| - if_chain! { |
228 |
| - if let ExprKind::Call(repl_func, _) = src.kind; |
229 |
| - if !in_external_macro(cx.tcx.sess, expr_span); |
230 |
| - if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind; |
231 |
| - if let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id(); |
232 |
| - if is_diag_trait_item(cx, repl_def_id, sym::Default) |
233 |
| - || is_default_equivalent_ctor(cx, repl_def_id, repl_func_qpath); |
234 |
| - |
235 |
| - then { |
236 |
| - span_lint_and_then( |
237 |
| - cx, |
238 |
| - MEM_REPLACE_WITH_DEFAULT, |
239 |
| - expr_span, |
240 |
| - "replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`", |
241 |
| - |diag| { |
242 |
| - if !in_macro(expr_span) { |
243 |
| - let suggestion = format!("std::mem::take({})", snippet(cx, dest.span, "")); |
244 |
| - |
245 |
| - diag.span_suggestion( |
246 |
| - expr_span, |
247 |
| - "consider using", |
248 |
| - suggestion, |
249 |
| - Applicability::MachineApplicable |
250 |
| - ); |
251 |
| - } |
| 217 | + diag.span_suggestion( |
| 218 | + expr_span, |
| 219 | + "consider using", |
| 220 | + suggestion, |
| 221 | + Applicability::MachineApplicable, |
| 222 | + ); |
252 | 223 | }
|
253 |
| - ); |
254 |
| - } |
| 224 | + }, |
| 225 | + ); |
255 | 226 | }
|
256 | 227 | }
|
257 | 228 |
|
|
0 commit comments