]> git.lizzy.rs Git - rust.git/blobdiff - src/tools/clippy/clippy_lints/src/default.rs
Rollup merge of #90741 - mbartlett21:patch-4, r=dtolnay
[rust.git] / src / tools / clippy / clippy_lints / src / default.rs
index db8f2171348f7046ffa96bae0a3a2519471a1e4d..a0b137efe221a3bc8113a2936403bbce99f9b874 100644 (file)
@@ -1,6 +1,7 @@
 use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg};
 use clippy_utils::source::snippet_with_macro_callsite;
-use clippy_utils::{any_parent_is_automatically_derived, contains_name, in_macro, match_def_path, paths};
+use clippy_utils::ty::{has_drop, is_copy};
+use clippy_utils::{any_parent_is_automatically_derived, contains_name, match_def_path, paths};
 use if_chain::if_chain;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
@@ -28,6 +29,7 @@
     /// // Good
     /// let s = String::default();
     /// ```
+    #[clippy::version = "pre 1.29.0"]
     pub DEFAULT_TRAIT_ACCESS,
     pedantic,
     "checks for literal calls to `Default::default()`"
@@ -61,6 +63,7 @@
     ///     .. Default::default()
     /// };
     /// ```
+    #[clippy::version = "1.49.0"]
     pub FIELD_REASSIGN_WITH_DEFAULT,
     style,
     "binding initialized with Default should have its fields set in the initializer"
@@ -77,7 +80,7 @@ pub struct Default {
 impl LateLintPass<'_> for Default {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         if_chain! {
-            if !in_macro(expr.span);
+            if !expr.span.from_expansion();
             // Avoid cases already linted by `field_reassign_with_default`
             if !self.reassigned_linted.contains(&expr.span);
             if let ExprKind::Call(path, ..) = expr.kind;
@@ -124,7 +127,7 @@ fn check_block<'tcx>(&mut self, cx: &LateContext<'tcx>, block: &Block<'tcx>) {
                 if let StmtKind::Local(local) = stmt.kind;
                 if let Some(expr) = local.init;
                 if !any_parent_is_automatically_derived(cx.tcx, expr.hir_id);
-                if !in_macro(expr.span);
+                if !expr.span.from_expansion();
                 // only take bindings to identifiers
                 if let PatKind::Binding(_, binding_id, ident, _) = local.pat.kind;
                 // only when assigning `... = Default::default()`
@@ -139,6 +142,13 @@ fn check_block<'tcx>(&mut self, cx: &LateContext<'tcx>, block: &Block<'tcx>) {
                     .fields
                     .iter()
                     .all(|field| field.vis.is_accessible_from(module_did, cx.tcx));
+                let all_fields_are_copy = variant
+                    .fields
+                    .iter()
+                    .all(|field| {
+                        is_copy(cx, cx.tcx.type_of(field.did))
+                    });
+                if !has_drop(cx, binding_type) || all_fields_are_copy;
                 then {
                     (local, variant, ident.name, binding_type, expr.span)
                 } else {