]> git.lizzy.rs Git - rust.git/commitdiff
unit-arg - pr comments
authorTim Nielens <tim.nielens@gmail.com>
Wed, 26 Aug 2020 23:40:02 +0000 (01:40 +0200)
committerTim Nielens <tim.nielens@gmail.com>
Thu, 27 Aug 2020 17:36:28 +0000 (19:36 +0200)
clippy_lints/src/types.rs
clippy_lints/src/utils/mod.rs
tests/ui/unit_arg.rs
tests/ui/unit_arg.stderr
tests/ui/unit_arg_empty_blocks.stderr

index 3f5b3a5bcd5d79c2fb96f0e203a89ccbeac350f0..16e48d919164f9e7d4a5668875e4bd4b8b2c2e3d 100644 (file)
 use crate::consts::{constant, Constant};
 use crate::utils::paths;
 use crate::utils::{
-    clip, comparisons, differing_macro_contexts, higher, in_constant, int_bits, is_type_diagnostic_item,
+    clip, comparisons, differing_macro_contexts, higher, in_constant, indent_of, int_bits, is_type_diagnostic_item,
     last_path_segment, match_def_path, match_path, method_chain_args, multispan_sugg, numeric_literal::NumericLiteral,
     qpath_res, sext, snippet, snippet_opt, snippet_with_applicability, snippet_with_macro_callsite, span_lint,
-    span_lint_and_help, span_lint_and_sugg, span_lint_and_then, unsext,
+    span_lint_and_help, span_lint_and_sugg, span_lint_and_then, trim_multiline, unsext,
 };
 
 declare_clippy_lint! {
@@ -802,6 +802,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
     }
 }
 
+#[allow(clippy::too_many_lines)]
 fn lint_unit_args(cx: &LateContext<'_>, expr: &Expr<'_>, args_to_recover: &[&Expr<'_>]) {
     let mut applicability = Applicability::MachineApplicable;
     let (singular, plural) = if args_to_recover.len() > 1 {
@@ -856,18 +857,38 @@ fn lint_unit_args(cx: &LateContext<'_>, expr: &Expr<'_>, args_to_recover: &[&Exp
                 .filter(|arg| !is_empty_block(arg))
                 .filter_map(|arg| snippet_opt(cx, arg.span))
                 .collect();
+            let indent = indent_of(cx, expr.span).unwrap_or(0);
 
-            if let Some(mut sugg) = snippet_opt(cx, expr.span) {
-                arg_snippets.iter().for_each(|arg| {
-                    sugg = sugg.replacen(arg, "()", 1);
-                });
-                sugg = format!("{}{}{}", arg_snippets_without_empty_blocks.join("; "), "; ", sugg);
+            if let Some(expr_str) = snippet_opt(cx, expr.span) {
+                let expr_with_replacements = arg_snippets
+                    .iter()
+                    .fold(expr_str, |acc, arg| acc.replacen(arg, "()", 1));
+
+                // expr is not in a block statement or result expression position, wrap in a block
                 let parent_node = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(expr.hir_id));
-                if !matches!(parent_node, Some(Node::Block(_))) && !matches!(parent_node, Some(Node::Stmt(_))) {
-                    // expr is not in a block statement or result expression position, wrap in a block
-                    sugg = format!("{{ {} }}", sugg);
+                let wrap_in_block =
+                    !matches!(parent_node, Some(Node::Block(_))) && !matches!(parent_node, Some(Node::Stmt(_)));
+
+                let stmts_indent = if wrap_in_block { indent + 4 } else { indent };
+                let mut stmts_and_call = arg_snippets_without_empty_blocks.clone();
+                stmts_and_call.push(expr_with_replacements);
+                let mut stmts_and_call_str = stmts_and_call
+                    .into_iter()
+                    .enumerate()
+                    .map(|(i, v)| {
+                        let with_indent_prefix = if i > 0 { " ".repeat(stmts_indent) + &v } else { v };
+                        trim_multiline(with_indent_prefix.into(), true, Some(stmts_indent)).into_owned()
+                    })
+                    .collect::<Vec<String>>()
+                    .join(";\n");
+
+                if wrap_in_block {
+                    stmts_and_call_str = " ".repeat(stmts_indent) + &stmts_and_call_str;
+                    stmts_and_call_str = format!("{{\n{}\n{}}}", &stmts_and_call_str, " ".repeat(indent));
                 }
 
+                let sugg = stmts_and_call_str;
+
                 if arg_snippets_without_empty_blocks.is_empty() {
                     db.multipart_suggestion(
                         &format!("use {}unit literal{} instead", singular, plural),
index 2aef995cec44b9245d9092327d49cedc324a4345..d20b33c4a1d10c21a18bc872e30bbdbd7831a925 100644 (file)
@@ -662,7 +662,7 @@ pub fn expr_block<'a, T: LintContext>(
 
 /// Trim indentation from a multiline string with possibility of ignoring the
 /// first line.
-fn trim_multiline(s: Cow<'_, str>, ignore_first: bool, indent: Option<usize>) -> Cow<'_, str> {
+pub fn trim_multiline(s: Cow<'_, str>, ignore_first: bool, indent: Option<usize>) -> Cow<'_, str> {
     let s_space = trim_multiline_inner(s, ignore_first, indent, ' ');
     let s_tab = trim_multiline_inner(s_space, ignore_first, indent, '\t');
     trim_multiline_inner(s_tab, ignore_first, indent, ' ')
index 2e2bd054e42aa027231c3f9ebe8a376f214079c1..fec115ff29d6699cd82adafbf5d34dbcc1e25d3a 100644 (file)
@@ -1,5 +1,11 @@
 #![warn(clippy::unit_arg)]
-#![allow(clippy::no_effect, unused_must_use, unused_variables, clippy::unused_unit)]
+#![allow(
+    clippy::no_effect,
+    unused_must_use,
+    unused_variables,
+    clippy::unused_unit,
+    clippy::or_fun_call
+)]
 
 use std::fmt::Debug;
 
index 2a0cc1f18e27cf04878fc3ca1c56932e7a5e5e2c..90fee3aab23b0c96cd3b8cff521f208ad8cff55d 100644 (file)
@@ -1,5 +1,5 @@
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:23:5
+  --> $DIR/unit_arg.rs:29:5
    |
 LL | /     foo({
 LL | |         1;
@@ -15,22 +15,24 @@ help: or move the expression in front of the call and replace it with the unit l
    |
 LL |     {
 LL |         1;
-LL |     }; foo(());
+LL |     };
+LL |     foo(());
    |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:26:5
+  --> $DIR/unit_arg.rs:32:5
    |
 LL |     foo(foo(1));
    |     ^^^^^^^^^^^
    |
 help: move the expression in front of the call and replace it with the unit literal `()`
    |
-LL |     foo(1); foo(());
-   |     ^^^^^^^^^^^^^^^
+LL |     foo(1);
+LL |     foo(());
+   |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:27:5
+  --> $DIR/unit_arg.rs:33:5
    |
 LL | /     foo({
 LL | |         foo(1);
@@ -47,11 +49,12 @@ help: or move the expression in front of the call and replace it with the unit l
 LL |     {
 LL |         foo(1);
 LL |         foo(2);
-LL |     }; foo(());
+LL |     };
+LL |     foo(());
    |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:32:5
+  --> $DIR/unit_arg.rs:38:5
    |
 LL | /     b.bar({
 LL | |         1;
@@ -66,22 +69,25 @@ help: or move the expression in front of the call and replace it with the unit l
    |
 LL |     {
 LL |         1;
-LL |     }; b.bar(());
+LL |     };
+LL |     b.bar(());
    |
 
 error: passing unit values to a function
-  --> $DIR/unit_arg.rs:35:5
+  --> $DIR/unit_arg.rs:41:5
    |
 LL |     taking_multiple_units(foo(0), foo(1));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: move the expressions in front of the call and replace them with the unit literal `()`
    |
-LL |     foo(0); foo(1); taking_multiple_units((), ());
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     foo(0);
+LL |     foo(1);
+LL |     taking_multiple_units((), ());
+   |
 
 error: passing unit values to a function
-  --> $DIR/unit_arg.rs:36:5
+  --> $DIR/unit_arg.rs:42:5
    |
 LL | /     taking_multiple_units(foo(0), {
 LL | |         foo(1);
@@ -95,14 +101,16 @@ LL |         foo(2)
    |
 help: or move the expressions in front of the call and replace them with the unit literal `()`
    |
-LL |     foo(0); {
+LL |     foo(0);
+LL |     {
 LL |         foo(1);
 LL |         foo(2);
-LL |     }; taking_multiple_units((), ());
+LL |     };
+LL |     taking_multiple_units((), ());
    |
 
 error: passing unit values to a function
-  --> $DIR/unit_arg.rs:40:5
+  --> $DIR/unit_arg.rs:46:5
    |
 LL | /     taking_multiple_units(
 LL | |         {
@@ -124,53 +132,50 @@ LL |             foo(3)
 help: or move the expressions in front of the call and replace them with the unit literal `()`
    |
 LL |     {
-LL |             foo(0);
-LL |             foo(1);
-LL |         }; {
-LL |             foo(2);
-LL |             foo(3);
+LL |         foo(0);
+LL |         foo(1);
+LL |     };
+LL |     {
+LL |         foo(2);
  ...
 
-error: use of `or` followed by a function call
-  --> $DIR/unit_arg.rs:51:10
-   |
-LL |     None.or(Some(foo(2)));
-   |          ^^^^^^^^^^^^^^^^ help: try this: `or_else(|| Some(foo(2)))`
-   |
-   = note: `-D clippy::or-fun-call` implied by `-D warnings`
-
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:51:13
+  --> $DIR/unit_arg.rs:57:13
    |
 LL |     None.or(Some(foo(2)));
    |             ^^^^^^^^^^^^
    |
 help: move the expression in front of the call and replace it with the unit literal `()`
    |
-LL |     None.or({ foo(2); Some(()) });
-   |             ^^^^^^^^^^^^^^^^^^^^
+LL |     None.or({
+LL |         foo(2);
+LL |         Some(())
+LL |     });
+   |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:54:5
+  --> $DIR/unit_arg.rs:60:5
    |
 LL |     foo(foo(()))
    |     ^^^^^^^^^^^^
    |
 help: move the expression in front of the call and replace it with the unit literal `()`
    |
-LL |     foo(()); foo(())
+LL |     foo(());
+LL |     foo(())
    |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:87:5
+  --> $DIR/unit_arg.rs:93:5
    |
 LL |     Some(foo(1))
    |     ^^^^^^^^^^^^
    |
 help: move the expression in front of the call and replace it with the unit literal `()`
    |
-LL |     foo(1); Some(())
+LL |     foo(1);
+LL |     Some(())
    |
 
-error: aborting due to 11 previous errors
+error: aborting due to 10 previous errors
 
index 4cbbc8b8cd43ed2c5c465d9617e7785faf23546c..456b12a2c6b1654a7b18b2325603f740593ce8aa 100644 (file)
@@ -24,8 +24,9 @@ LL |     taking_two_units({}, foo(0));
    |
 help: move the expression in front of the call and replace it with the unit literal `()`
    |
-LL |     foo(0); taking_two_units((), ());
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     foo(0);
+LL |     taking_two_units((), ());
+   |
 
 error: passing unit values to a function
   --> $DIR/unit_arg_empty_blocks.rs:18:5
@@ -35,8 +36,10 @@ LL |     taking_three_units({}, foo(0), foo(1));
    |
 help: move the expressions in front of the call and replace them with the unit literal `()`
    |
-LL |     foo(0); foo(1); taking_three_units((), (), ());
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     foo(0);
+LL |     foo(1);
+LL |     taking_three_units((), (), ());
+   |
 
 error: aborting due to 4 previous errors