about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCatherine Flores <catherine.3.flores@gmail.com>2023-07-25 17:56:43 -0500
committerCatherine Flores <catherine.3.flores@gmail.com>2023-07-25 18:09:59 -0500
commit90947e95ad8c26156739566c7ad1e52013b63a93 (patch)
treed09190acff99af654a8553b8dcd6d313eec8c0f8
parent2153c0fcc893534d61b4d66de80e615e7bff6017 (diff)
downloadrust-90947e95ad8c26156739566c7ad1e52013b63a93.tar.gz
rust-90947e95ad8c26156739566c7ad1e52013b63a93.zip
[`arc_with_non_send_sync`]: Check if it's macro-generated
-rw-r--r--clippy_lints/src/arc_with_non_send_sync.rs12
-rw-r--r--tests/ui/arc_with_non_send_sync.rs30
-rw-r--r--tests/ui/arc_with_non_send_sync.stderr6
3 files changed, 37 insertions, 11 deletions
diff --git a/clippy_lints/src/arc_with_non_send_sync.rs b/clippy_lints/src/arc_with_non_send_sync.rs
index 7adcd9ad055..35a04b5e44a 100644
--- a/clippy_lints/src/arc_with_non_send_sync.rs
+++ b/clippy_lints/src/arc_with_non_send_sync.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::last_path_segment;
 use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
+use clippy_utils::{is_from_proc_macro, last_path_segment};
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
@@ -38,10 +38,11 @@ declare_clippy_lint! {
 }
 declare_lint_pass!(ArcWithNonSendSync => [ARC_WITH_NON_SEND_SYNC]);
 
-impl LateLintPass<'_> for ArcWithNonSendSync {
-    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
-        let ty = cx.typeck_results().expr_ty(expr);
-        if is_type_diagnostic_item(cx, ty, sym::Arc)
+impl<'tcx> LateLintPass<'tcx> for ArcWithNonSendSync {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
+        if !expr.span.from_expansion()
+            && let ty = cx.typeck_results().expr_ty(expr)
+            && is_type_diagnostic_item(cx, ty, sym::Arc)
             && let ExprKind::Call(func, [arg]) = expr.kind
             && let ExprKind::Path(func_path) = func.kind
             && last_path_segment(&func_path).ident.name == sym::new
@@ -54,6 +55,7 @@ impl LateLintPass<'_> for ArcWithNonSendSync {
             && let Some(sync) = cx.tcx.lang_items().sync_trait()
             && let [is_send, is_sync] = [send, sync].map(|id| implements_trait(cx, arg_ty, id, &[]))
             && !(is_send && is_sync)
+            && !is_from_proc_macro(cx, expr)
         {
             span_lint_and_then(
                 cx,
diff --git a/tests/ui/arc_with_non_send_sync.rs b/tests/ui/arc_with_non_send_sync.rs
index b6fcca0a791..2940c273255 100644
--- a/tests/ui/arc_with_non_send_sync.rs
+++ b/tests/ui/arc_with_non_send_sync.rs
@@ -1,6 +1,12 @@
+//@aux-build:proc_macros.rs:proc-macro
 #![warn(clippy::arc_with_non_send_sync)]
 #![allow(unused_variables)]
+
+#[macro_use]
+extern crate proc_macros;
+
 use std::cell::RefCell;
+use std::ptr::{null, null_mut};
 use std::sync::{Arc, Mutex};
 
 fn foo<T>(x: T) {
@@ -11,14 +17,32 @@ fn issue11076<T>() {
     let a: Arc<Vec<T>> = Arc::new(Vec::new());
 }
 
+fn issue11232() {
+    external! {
+        let a: Arc<*const u8> = Arc::new(null());
+        let a: Arc<*mut u8> = Arc::new(null_mut());
+    }
+    with_span! {
+        span
+        let a: Arc<*const u8> = Arc::new(null());
+        let a: Arc<*mut u8> = Arc::new(null_mut());
+    }
+}
+
 fn main() {
     let _ = Arc::new(42);
 
-    // !Sync
     let _ = Arc::new(RefCell::new(42));
+    //~^ ERROR: usage of an `Arc` that is not `Send` or `Sync`
+    //~| NOTE: the trait `Sync` is not implemented for `RefCell<i32>`
+
     let mutex = Mutex::new(1);
-    // !Send
     let _ = Arc::new(mutex.lock().unwrap());
-    // !Send + !Sync
+    //~^ ERROR: usage of an `Arc` that is not `Send` or `Sync`
+    //~| NOTE: the trait `Send` is not implemented for `MutexGuard<'_, i32>`
+
     let _ = Arc::new(&42 as *const i32);
+    //~^ ERROR: usage of an `Arc` that is not `Send` or `Sync`
+    //~| NOTE: the trait `Send` is not implemented for `*const i32`
+    //~| NOTE: the trait `Sync` is not implemented for `*const i32`
 }
diff --git a/tests/ui/arc_with_non_send_sync.stderr b/tests/ui/arc_with_non_send_sync.stderr
index 7633b38dfb5..de3f2fb9e16 100644
--- a/tests/ui/arc_with_non_send_sync.stderr
+++ b/tests/ui/arc_with_non_send_sync.stderr
@@ -1,5 +1,5 @@
 error: usage of an `Arc` that is not `Send` or `Sync`
-  --> $DIR/arc_with_non_send_sync.rs:18:13
+  --> $DIR/arc_with_non_send_sync.rs:35:13
    |
 LL |     let _ = Arc::new(RefCell::new(42));
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -10,7 +10,7 @@ LL |     let _ = Arc::new(RefCell::new(42));
    = note: `-D clippy::arc-with-non-send-sync` implied by `-D warnings`
 
 error: usage of an `Arc` that is not `Send` or `Sync`
-  --> $DIR/arc_with_non_send_sync.rs:21:13
+  --> $DIR/arc_with_non_send_sync.rs:40:13
    |
 LL |     let _ = Arc::new(mutex.lock().unwrap());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -20,7 +20,7 @@ LL |     let _ = Arc::new(mutex.lock().unwrap());
    = help: consider using an `Rc` instead or wrapping the inner type with a `Mutex`
 
 error: usage of an `Arc` that is not `Send` or `Sync`
-  --> $DIR/arc_with_non_send_sync.rs:23:13
+  --> $DIR/arc_with_non_send_sync.rs:44:13
    |
 LL |     let _ = Arc::new(&42 as *const i32);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^