about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSamuel Tardieu <sam@rfc1149.net>2025-03-06 23:08:15 +0100
committerSamuel Tardieu <sam@rfc1149.net>2025-04-10 07:46:45 +0200
commit0aa0d074cd1ce3f58eaffcf6019c1a236adc4dc1 (patch)
treef01ccdbf62cf5772ff574fafe875a952743b6986
parent253ecb9d7dfbfe3110c7e58e5017b31058f96d80 (diff)
downloadrust-0aa0d074cd1ce3f58eaffcf6019c1a236adc4dc1.tar.gz
rust-0aa0d074cd1ce3f58eaffcf6019c1a236adc4dc1.zip
Remove brackets around type name when it is no longer a prefix
When `<T>::default()` is replaced by `T` when `T` is a singleton,
the brackets around the type name can be removed.
-rw-r--r--clippy_lints/src/default_constructed_unit_structs.rs12
-rw-r--r--tests/ui/default_constructed_unit_structs.fixed8
-rw-r--r--tests/ui/default_constructed_unit_structs.rs5
-rw-r--r--tests/ui/default_constructed_unit_structs.stderr22
4 files changed, 37 insertions, 10 deletions
diff --git a/clippy_lints/src/default_constructed_unit_structs.rs b/clippy_lints/src/default_constructed_unit_structs.rs
index 7410e0a6705..f8a9037fc80 100644
--- a/clippy_lints/src/default_constructed_unit_structs.rs
+++ b/clippy_lints/src/default_constructed_unit_structs.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_ty_alias;
-use clippy_utils::sugg::DiagExt as _;
+use clippy_utils::source::SpanRangeExt as _;
 use hir::ExprKind;
 use hir::def::Res;
 use rustc_errors::Applicability;
@@ -74,16 +74,20 @@ impl LateLintPass<'_> for DefaultConstructedUnitStructs {
             // do not suggest replacing an expression by a type name with placeholders
             && !base.is_suggestable_infer_ty()
         {
+            let mut removals = vec![(expr.span.with_lo(qpath.qself_span().hi()), String::new())];
+            if expr.span.with_source_text(cx, |s| s.starts_with('<')) == Some(true) {
+                // Remove `<`, '>` has already been removed by the existing removal expression.
+                removals.push((expr.span.with_hi(qpath.qself_span().lo()), String::new()));
+            }
             span_lint_and_then(
                 cx,
                 DEFAULT_CONSTRUCTED_UNIT_STRUCTS,
                 expr.span,
                 "use of `default` to create a unit struct",
                 |diag| {
-                    diag.suggest_remove_item(
-                        cx,
-                        expr.span.with_lo(qpath.qself_span().hi()),
+                    diag.multipart_suggestion(
                         "remove this call to `default`",
+                        removals,
                         Applicability::MachineApplicable,
                     );
                 },
diff --git a/tests/ui/default_constructed_unit_structs.fixed b/tests/ui/default_constructed_unit_structs.fixed
index 3beddca6fb1..1ca9be0cedd 100644
--- a/tests/ui/default_constructed_unit_structs.fixed
+++ b/tests/ui/default_constructed_unit_structs.fixed
@@ -8,7 +8,8 @@ struct UnitStruct;
 impl UnitStruct {
     fn new() -> Self {
         //should lint
-        Self//~^ default_constructed_unit_structs
+        Self
+        //~^ default_constructed_unit_structs
     }
 }
 
@@ -168,4 +169,9 @@ fn issue12654() {
     fn f(_g: G) {}
 
     f(<_>::default());
+    f(G);
+    //~^ default_constructed_unit_structs
+
+    // No lint because `as Default` hides the singleton
+    f(<G as Default>::default());
 }
diff --git a/tests/ui/default_constructed_unit_structs.rs b/tests/ui/default_constructed_unit_structs.rs
index 571f7cde26a..99eb8913fc3 100644
--- a/tests/ui/default_constructed_unit_structs.rs
+++ b/tests/ui/default_constructed_unit_structs.rs
@@ -169,4 +169,9 @@ fn issue12654() {
     fn f(_g: G) {}
 
     f(<_>::default());
+    f(<G>::default());
+    //~^ default_constructed_unit_structs
+
+    // No lint because `as Default` hides the singleton
+    f(<G as Default>::default());
 }
diff --git a/tests/ui/default_constructed_unit_structs.stderr b/tests/ui/default_constructed_unit_structs.stderr
index 7c0f4c0d4ac..97fad792e4f 100644
--- a/tests/ui/default_constructed_unit_structs.stderr
+++ b/tests/ui/default_constructed_unit_structs.stderr
@@ -1,10 +1,10 @@
 error: use of `default` to create a unit struct
   --> tests/ui/default_constructed_unit_structs.rs:11:9
    |
-LL |           Self::default()
-   |  _________^^^^-^^^^^^^^^^
-LL | |
-   | |________- help: remove this call to `default`
+LL |         Self::default()
+   |         ^^^^-----------
+   |             |
+   |             help: remove this call to `default`
    |
    = note: `-D clippy::default-constructed-unit-structs` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::default_constructed_unit_structs)]`
@@ -49,5 +49,17 @@ LL |     let _ = UnitStruct::default();
    |                       |
    |                       help: remove this call to `default`
 
-error: aborting due to 6 previous errors
+error: use of `default` to create a unit struct
+  --> tests/ui/default_constructed_unit_structs.rs:172:7
+   |
+LL |     f(<G>::default());
+   |       ^^^^^^^^^^^^^^
+   |
+help: remove this call to `default`
+   |
+LL -     f(<G>::default());
+LL +     f(G);
+   |
+
+error: aborting due to 7 previous errors