about summary refs log tree commit diff
diff options
context:
space:
mode:
authorlyj <lyj@everton>2021-06-02 13:31:23 +0800
committerlyj <lyj@everton>2021-06-03 16:25:27 +0800
commit84c511facf6534394eaab76299c2953fcf47e76f (patch)
treef27a63fbd417bc82db94919d67071de9158d5114
parent5f746a1c2ae130ef84704c941b962075af6693ac (diff)
downloadrust-84c511facf6534394eaab76299c2953fcf47e76f.tar.gz
rust-84c511facf6534394eaab76299c2953fcf47e76f.zip
rc_mutex
-rw-r--r--clippy_lints/src/types/mod.rs11
-rw-r--r--clippy_lints/src/types/rc_mutex.rs39
2 files changed, 49 insertions, 1 deletions
diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs
index 70b9e8adef8..acf00825b7a 100644
--- a/clippy_lints/src/types/mod.rs
+++ b/clippy_lints/src/types/mod.rs
@@ -7,6 +7,7 @@ mod redundant_allocation;
 mod type_complexity;
 mod utils;
 mod vec_box;
+mod rc_mutex;
 
 use rustc_hir as hir;
 use rustc_hir::intravisit::FnKind;
@@ -250,12 +251,19 @@ declare_clippy_lint! {
     "usage of very complex types that might be better factored into `type` definitions"
 }
 
+declare_clippy_lint! {
+    /// TODO
+    pub RC_MUTEX,
+    restriction,
+    "usage of Mutex inside Rc"
+}
+
 pub struct Types {
     vec_box_size_threshold: u64,
     type_complexity_threshold: u64,
 }
 
-impl_lint_pass!(Types => [BOX_VEC, VEC_BOX, OPTION_OPTION, LINKEDLIST, BORROWED_BOX, REDUNDANT_ALLOCATION, RC_BUFFER, TYPE_COMPLEXITY]);
+impl_lint_pass!(Types => [BOX_VEC, VEC_BOX, OPTION_OPTION, LINKEDLIST, BORROWED_BOX, REDUNDANT_ALLOCATION, RC_BUFFER, TYPE_COMPLEXITY,RC_MUTEX]);
 
 impl<'tcx> LateLintPass<'tcx> for Types {
     fn check_fn(&mut self, cx: &LateContext<'_>, _: FnKind<'_>, decl: &FnDecl<'_>, _: &Body<'_>, _: Span, id: HirId) {
@@ -375,6 +383,7 @@ impl Types {
                     triggered |= vec_box::check(cx, hir_ty, qpath, def_id, self.vec_box_size_threshold);
                     triggered |= option_option::check(cx, hir_ty, qpath, def_id);
                     triggered |= linked_list::check(cx, hir_ty, def_id);
+                    triggered |= rc_mutex::check(cx, hir_ty, qpath, def_id);
 
                     if triggered {
                         return;
diff --git a/clippy_lints/src/types/rc_mutex.rs b/clippy_lints/src/types/rc_mutex.rs
new file mode 100644
index 00000000000..b53b55fd01c
--- /dev/null
+++ b/clippy_lints/src/types/rc_mutex.rs
@@ -0,0 +1,39 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::{ get_qpath_generic_tys,is_ty_param_diagnostic_item};
+use clippy_utils::source::snippet_with_applicability;
+use rustc_errors::Applicability;
+use rustc_hir::{self as hir, def_id::DefId, QPath};
+use rustc_lint::LateContext;
+use rustc_span::symbol::sym;
+// use rustc_middle::ty::Adt;
+
+use super::RC_MUTEX;
+
+pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool {
+    if cx.tcx.is_diagnostic_item(sym::Rc, def_id) {
+        if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym!(mutex_type)) {
+            let mut applicability = Applicability::MachineApplicable;
+
+            let inner_span = match get_qpath_generic_tys(qpath).skip(1).next() {
+                Some(ty) => ty.span,
+                None => return false,
+            };
+
+            span_lint_and_sugg(
+                cx,
+                RC_MUTEX,
+                hir_ty.span,
+                "you seem to be trying to use `Rc<Mutex<T>>`. Consider using `Rc<RefCell<T>>`",
+                "try",
+                format!(
+                    "Rc<RefCell<{}>>",
+                    snippet_with_applicability(cx, inner_span, "..", &mut applicability)
+                ),
+                applicability,
+            );
+            return true;
+        }
+    }
+
+    false
+}