about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/non_copy_const.rs15
-rw-r--r--tests/ui/borrow_interior_mutable_const.rs35
-rw-r--r--tests/ui/borrow_interior_mutable_const.stderr32
3 files changed, 64 insertions, 18 deletions
diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs
index 031d69e86a1..f1df634701d 100644
--- a/clippy_lints/src/non_copy_const.rs
+++ b/clippy_lints/src/non_copy_const.rs
@@ -211,8 +211,21 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
                             needs_check_adjustment = false;
                         },
                         ExprKind::Field(..) => {
-                            dereferenced_expr = parent_expr;
                             needs_check_adjustment = true;
+
+                            // Check whether implicit dereferences happened;
+                            // if so, no need to go further up
+                            // because of the same reason as the `ExprKind::Unary` case.
+                            if cx
+                                .typeck_results()
+                                .expr_adjustments(dereferenced_expr)
+                                .iter()
+                                .any(|adj| matches!(adj.kind, Adjust::Deref(_)))
+                            {
+                                break;
+                            }
+
+                            dereferenced_expr = parent_expr;
                         },
                         ExprKind::Index(e, _) if ptr::eq(&**e, cur_expr) => {
                             // `e[i]` => desugared to `*Index::index(&e, i)`,
diff --git a/tests/ui/borrow_interior_mutable_const.rs b/tests/ui/borrow_interior_mutable_const.rs
index fef9f4f39f8..a414832bcd3 100644
--- a/tests/ui/borrow_interior_mutable_const.rs
+++ b/tests/ui/borrow_interior_mutable_const.rs
@@ -2,7 +2,7 @@
 #![allow(clippy::declare_interior_mutable_const, clippy::ref_in_deref)]
 
 use std::borrow::Cow;
-use std::cell::Cell;
+use std::cell::{Cell, UnsafeCell};
 use std::fmt::Display;
 use std::sync::atomic::{AtomicUsize, Ordering};
 use std::sync::Once;
@@ -30,6 +30,37 @@ impl Trait<u32> for u64 {
     const ATOMIC: AtomicUsize = AtomicUsize::new(9);
 }
 
+// This is just a pointer that can be safely dereferended,
+// it's semantically the same as `&'static T`;
+// but it isn't allowed to make a static reference from an arbitrary integer value at the moment.
+// For more information, please see the issue #5918.
+pub struct StaticRef<T> {
+    ptr: *const T,
+}
+
+impl<T> StaticRef<T> {
+    /// Create a new `StaticRef` from a raw pointer
+    ///
+    /// ## Safety
+    ///
+    /// Callers must pass in a reference to statically allocated memory which
+    /// does not overlap with other values.
+    pub const unsafe fn new(ptr: *const T) -> StaticRef<T> {
+        StaticRef { ptr }
+    }
+}
+
+impl<T> std::ops::Deref for StaticRef<T> {
+    type Target = T;
+
+    fn deref(&self) -> &'static T {
+        unsafe { &*self.ptr }
+    }
+}
+
+// use a tuple to make sure referencing a field behind a pointer isn't linted.
+const CELL_REF: StaticRef<(UnsafeCell<u32>,)> = unsafe { StaticRef::new(std::ptr::null()) };
+
 fn main() {
     ATOMIC.store(1, Ordering::SeqCst); //~ ERROR interior mutability
     assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); //~ ERROR interior mutability
@@ -82,4 +113,6 @@ fn main() {
     assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); //~ ERROR interior mutability
 
     assert_eq!(NO_ANN.to_string(), "70"); // should never lint this.
+
+    let _ = &CELL_REF.0;
 }
diff --git a/tests/ui/borrow_interior_mutable_const.stderr b/tests/ui/borrow_interior_mutable_const.stderr
index dc738064a17..1e0b3e4d20a 100644
--- a/tests/ui/borrow_interior_mutable_const.stderr
+++ b/tests/ui/borrow_interior_mutable_const.stderr
@@ -1,5 +1,5 @@
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:34:5
+  --> $DIR/borrow_interior_mutable_const.rs:65:5
    |
 LL |     ATOMIC.store(1, Ordering::SeqCst); //~ ERROR interior mutability
    |     ^^^^^^
@@ -8,7 +8,7 @@ LL |     ATOMIC.store(1, Ordering::SeqCst); //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:35:16
+  --> $DIR/borrow_interior_mutable_const.rs:66:16
    |
 LL |     assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); //~ ERROR interior mutability
    |                ^^^^^^
@@ -16,7 +16,7 @@ LL |     assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); //~ ERROR interior mutabi
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:38:22
+  --> $DIR/borrow_interior_mutable_const.rs:69:22
    |
 LL |     let _once_ref = &ONCE_INIT; //~ ERROR interior mutability
    |                      ^^^^^^^^^
@@ -24,7 +24,7 @@ LL |     let _once_ref = &ONCE_INIT; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:39:25
+  --> $DIR/borrow_interior_mutable_const.rs:70:25
    |
 LL |     let _once_ref_2 = &&ONCE_INIT; //~ ERROR interior mutability
    |                         ^^^^^^^^^
@@ -32,7 +32,7 @@ LL |     let _once_ref_2 = &&ONCE_INIT; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:40:27
+  --> $DIR/borrow_interior_mutable_const.rs:71:27
    |
 LL |     let _once_ref_4 = &&&&ONCE_INIT; //~ ERROR interior mutability
    |                           ^^^^^^^^^
@@ -40,7 +40,7 @@ LL |     let _once_ref_4 = &&&&ONCE_INIT; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:41:26
+  --> $DIR/borrow_interior_mutable_const.rs:72:26
    |
 LL |     let _once_mut = &mut ONCE_INIT; //~ ERROR interior mutability
    |                          ^^^^^^^^^
@@ -48,7 +48,7 @@ LL |     let _once_mut = &mut ONCE_INIT; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:52:14
+  --> $DIR/borrow_interior_mutable_const.rs:83:14
    |
 LL |     let _ = &ATOMIC_TUPLE; //~ ERROR interior mutability
    |              ^^^^^^^^^^^^
@@ -56,7 +56,7 @@ LL |     let _ = &ATOMIC_TUPLE; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:53:14
+  --> $DIR/borrow_interior_mutable_const.rs:84:14
    |
 LL |     let _ = &ATOMIC_TUPLE.0; //~ ERROR interior mutability
    |              ^^^^^^^^^^^^
@@ -64,7 +64,7 @@ LL |     let _ = &ATOMIC_TUPLE.0; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:54:19
+  --> $DIR/borrow_interior_mutable_const.rs:85:19
    |
 LL |     let _ = &(&&&&ATOMIC_TUPLE).0; //~ ERROR interior mutability
    |                   ^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL |     let _ = &(&&&&ATOMIC_TUPLE).0; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:55:14
+  --> $DIR/borrow_interior_mutable_const.rs:86:14
    |
 LL |     let _ = &ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
    |              ^^^^^^^^^^^^
@@ -80,7 +80,7 @@ LL |     let _ = &ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:56:13
+  --> $DIR/borrow_interior_mutable_const.rs:87:13
    |
 LL |     let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); //~ ERROR interior mutability
    |             ^^^^^^^^^^^^
@@ -88,7 +88,7 @@ LL |     let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); //~ ERROR interior mu
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:62:13
+  --> $DIR/borrow_interior_mutable_const.rs:93:13
    |
 LL |     let _ = ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
    |             ^^^^^^^^^^^^
@@ -96,7 +96,7 @@ LL |     let _ = ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:67:5
+  --> $DIR/borrow_interior_mutable_const.rs:98:5
    |
 LL |     CELL.set(2); //~ ERROR interior mutability
    |     ^^^^
@@ -104,7 +104,7 @@ LL |     CELL.set(2); //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:68:16
+  --> $DIR/borrow_interior_mutable_const.rs:99:16
    |
 LL |     assert_eq!(CELL.get(), 6); //~ ERROR interior mutability
    |                ^^^^
@@ -112,7 +112,7 @@ LL |     assert_eq!(CELL.get(), 6); //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:81:5
+  --> $DIR/borrow_interior_mutable_const.rs:112:5
    |
 LL |     u64::ATOMIC.store(5, Ordering::SeqCst); //~ ERROR interior mutability
    |     ^^^^^^^^^^^
@@ -120,7 +120,7 @@ LL |     u64::ATOMIC.store(5, Ordering::SeqCst); //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:82:16
+  --> $DIR/borrow_interior_mutable_const.rs:113:16
    |
 LL |     assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); //~ ERROR interior mutability
    |                ^^^^^^^^^^^