about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRobin Schoonover <robin@cornhooves.org>2020-09-13 22:17:10 -0600
committerRobin Schoonover <robin@cornhooves.org>2020-09-14 17:08:14 -0600
commit2dd7175d60e070c7ee2b4609bdb17eae16e381f0 (patch)
tree971026c5ecb8f4f1bd40613201bac1a511aac05f
parent1b5317f68b2b55803d5051e9945f9a33817fccef (diff)
Apply rc_buffer lint to Arc<T>
-rw-r--r--clippy_lints/src/types.rs40
-rw-r--r--tests/ui/rc_buffer_arc.rs13
-rw-r--r--tests/ui/rc_buffer_arc.stderr28
3 files changed, 81 insertions, 0 deletions
diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs
index 5f3a2e0b6d4..da04d07885b 100644
--- a/clippy_lints/src/types.rs
+++ b/clippy_lints/src/types.rs
@@ -480,6 +480,46 @@ impl Types {
                             );
                             return; // don't recurse into the type
                         }
+                    } else if cx.tcx.is_diagnostic_item(sym::Arc, def_id) {
+                        if let Some(alternate) = match_buffer_type(cx, qpath) {
+                            span_lint_and_sugg(
+                                cx,
+                                RC_BUFFER,
+                                hir_ty.span,
+                                "usage of `Arc<T>` when T is a buffer type",
+                                "try",
+                                format!("Arc<{}>", alternate),
+                                Applicability::MachineApplicable,
+                            );
+                            return; // don't recurse into the type
+                        }
+                        if match_type_parameter(cx, qpath, &paths::VEC).is_some() {
+                            let vec_ty = match &last_path_segment(qpath).args.unwrap().args[0] {
+                                GenericArg::Type(ty) => match &ty.kind {
+                                    TyKind::Path(qpath) => qpath,
+                                    _ => return,
+                                },
+                                _ => return,
+                            };
+                            let inner_span = match &last_path_segment(&vec_ty).args.unwrap().args[0] {
+                                GenericArg::Type(ty) => ty.span,
+                                _ => return,
+                            };
+                            let mut applicability = Applicability::MachineApplicable;
+                            span_lint_and_sugg(
+                                cx,
+                                RC_BUFFER,
+                                hir_ty.span,
+                                "usage of `Arc<T>` when T is a buffer type",
+                                "try",
+                                format!(
+                                    "Arc<[{}]>",
+                                    snippet_with_applicability(cx, inner_span, "..", &mut applicability)
+                                ),
+                                Applicability::MachineApplicable,
+                            );
+                            return; // don't recurse into the type
+                        }
                     } else if cx.tcx.is_diagnostic_item(sym!(vec_type), def_id) {
                         if_chain! {
                             // Get the _ part of Vec<_>
diff --git a/tests/ui/rc_buffer_arc.rs b/tests/ui/rc_buffer_arc.rs
new file mode 100644
index 00000000000..a878b0ab336
--- /dev/null
+++ b/tests/ui/rc_buffer_arc.rs
@@ -0,0 +1,13 @@
+use std::ffi::OsString;
+use std::path::PathBuf;
+use std::sync::Arc;
+
+#[warn(clippy::rc_buffer)]
+struct S {
+    a: Arc<String>,
+    b: Arc<PathBuf>,
+    c: Arc<Vec<u8>>,
+    d: Arc<OsString>,
+}
+
+fn main() {}
diff --git a/tests/ui/rc_buffer_arc.stderr b/tests/ui/rc_buffer_arc.stderr
new file mode 100644
index 00000000000..c4b01621046
--- /dev/null
+++ b/tests/ui/rc_buffer_arc.stderr
@@ -0,0 +1,28 @@
+error: usage of `Arc<T>` when T is a buffer type
+  --> $DIR/rc_buffer_arc.rs:7:8
+   |
+LL |     a: Arc<String>,
+   |        ^^^^^^^^^^^ help: try: `Arc<str>`
+   |
+   = note: `-D clippy::rc-buffer` implied by `-D warnings`
+
+error: usage of `Arc<T>` when T is a buffer type
+  --> $DIR/rc_buffer_arc.rs:8:8
+   |
+LL |     b: Arc<PathBuf>,
+   |        ^^^^^^^^^^^^ help: try: `Arc<std::path::Path>`
+
+error: usage of `Arc<T>` when T is a buffer type
+  --> $DIR/rc_buffer_arc.rs:9:8
+   |
+LL |     c: Arc<Vec<u8>>,
+   |        ^^^^^^^^^^^^ help: try: `Arc<[u8]>`
+
+error: usage of `Arc<T>` when T is a buffer type
+  --> $DIR/rc_buffer_arc.rs:10:8
+   |
+LL |     d: Arc<OsString>,
+   |        ^^^^^^^^^^^^^ help: try: `Arc<std::ffi::OsStr>`
+
+error: aborting due to 4 previous errors
+