diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 621b21429a9..99692de03aa 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -175,6 +175,7 @@ pub mod neg_cmp_op_on_partial_ord;
 pub mod neg_multiply;
 pub mod new_without_default;
 pub mod no_effect;
+pub mod non_copy_const;
 pub mod non_expressive_names;
 pub mod ok_if_let;
 pub mod open_options;
@@ -432,6 +433,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
     reg.register_late_lint_pass(box duration_subsec::DurationSubsec);
     reg.register_late_lint_pass(box default_trait_access::DefaultTraitAccess);
     reg.register_late_lint_pass(box indexing_slicing::IndexingSlicing);
+    reg.register_late_lint_pass(box non_copy_const::NonCopyConst);
 
     reg.register_lint_group("clippy_restriction", vec![
         arithmetic::FLOAT_ARITHMETIC,
@@ -640,6 +642,8 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
         new_without_default::NEW_WITHOUT_DEFAULT_DERIVE,
         no_effect::NO_EFFECT,
         no_effect::UNNECESSARY_OPERATION,
+        non_copy_const::BORROW_INTERIOR_MUTABLE_CONST,
+        non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST,
         non_expressive_names::JUST_UNDERSCORES_AND_DIGITS,
         non_expressive_names::MANY_SINGLE_CHAR_NAMES,
         ok_if_let::IF_LET_SOME_RESULT,
@@ -895,6 +899,8 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
         misc::CMP_NAN,
         misc::FLOAT_CMP,
         misc::MODULO_ONE,
+        non_copy_const::BORROW_INTERIOR_MUTABLE_CONST,
+        non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST,
         open_options::NONSENSICAL_OPEN_OPTIONS,
         ptr::MUT_FROM_REF,
         ranges::ITERATOR_STEP_BY_ZERO,
diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs
new file mode 100644
index 00000000000..5fcf54bc015
--- /dev/null
+++ b/clippy_lints/src/non_copy_const.rs
@@ -0,0 +1,268 @@
+//! Checks for uses of const which the type is not Freeze (Cell-free).
+//!
+//! This lint is **deny** by default.
+
+use rustc::lint::{LateContext, LateLintPass, Lint, LintArray, LintPass};
+use rustc::hir::*;
+use rustc::hir::def::Def;
+use rustc::ty::{self, TyRef, TypeFlags};
+use rustc::ty::adjustment::Adjust;
+use rustc_errors::Applicability;
+use rustc_typeck::hir_ty_to_ty;
+use syntax_pos::{DUMMY_SP, Span};
+use std::ptr;
+use crate::utils::{in_constant, in_macro, is_copy, span_lint_and_then};
+
+/// **What it does:** Checks for declaration of `const` items which is interior
+/// mutable (e.g. contains a `Cell`, `Mutex`, `AtomicXxxx` etc).
+///
+/// **Why is this bad?** Consts are copied everywhere they are referenced, i.e.
+/// every time you refer to the const a fresh instance of the `Cell` or `Mutex`
+/// or `AtomicXxxx` will be created, which defeats the whole purpose of using
+/// these types in the first place.
+///
+/// The `const` should better be replaced by a `static` item if a global
+/// variable is wanted, or replaced by a `const fn` if a constructor is wanted.
+///
+/// **Known problems:** A "non-constant" const item is a legacy way to supply an
+/// initialized value to downstream `static` items (e.g. the
+/// `std::sync::ONCE_INIT` constant). In this case the use of `const` is legit,
+/// and this lint should be suppressed.
+///
+/// **Example:**
+/// ```rust
+/// use std::sync::atomic::{Ordering::SeqCst, AtomicUsize};
+///
+/// // Bad.
+/// const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);
+/// CONST_ATOM.store(6, SeqCst);             // the content of the atomic is unchanged
+/// assert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct
+///
+/// // Good.
+/// static STATIC_ATOM: AtomicUsize = AtomicUsize::new(15);
+/// STATIC_ATOM.store(9, SeqCst);
+/// assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance
+/// ```
+declare_clippy_lint! {
+    pub DECLARE_INTERIOR_MUTABLE_CONST,
+    correctness,
+    "declaring const with interior mutability"
+}
+
+/// **What it does:** Checks if `const` items which is interior mutable (e.g.
+/// contains a `Cell`, `Mutex`, `AtomicXxxx` etc) has been borrowed directly.
+///
+/// **Why is this bad?** Consts are copied everywhere they are referenced, i.e.
+/// every time you refer to the const a fresh instance of the `Cell` or `Mutex`
+/// or `AtomicXxxx` will be created, which defeats the whole purpose of using
+/// these types in the first place.
+///
+/// The `const` value should be stored inside a `static` item.
+///
+/// **Known problems:** None
+///
+/// **Example:**
+/// ```rust
+/// use std::sync::atomic::{Ordering::SeqCst, AtomicUsize};
+/// const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);
+///
+/// // Bad.
+/// CONST_ATOM.store(6, SeqCst);             // the content of the atomic is unchanged
+/// assert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct
+///
+/// // Good.
+/// static STATIC_ATOM: AtomicUsize = CONST_ATOM;
+/// STATIC_ATOM.store(9, SeqCst);
+/// assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance
+/// ```
+declare_clippy_lint! {
+    pub BORROW_INTERIOR_MUTABLE_CONST,
+    correctness,
+    "referencing const with interior mutability"
+}
+
+#[derive(Copy, Clone)]
+enum Source {
+    Item {
+        item: Span,
+    },
+    Assoc {
+        item: Span,
+        ty: Span,
+    },
+    Expr {
+        expr: Span,
+    },
+}
+
+impl Source {
+    fn lint(&self) -> (&'static Lint, &'static str, Span) {
+        match self {
+            Source::Item { item } | Source::Assoc { item, .. } => (
+                DECLARE_INTERIOR_MUTABLE_CONST,
+                "a const item should never be interior mutable",
+                *item,
+            ),
+            Source::Expr { expr } => (
+                BORROW_INTERIOR_MUTABLE_CONST,
+                "a const item with interior mutability should not be borrowed",
+                *expr,
+            ),
+        }
+    }
+}
+
+fn verify_ty_bound<'a, 'tcx>(
+    cx: &LateContext<'a, 'tcx>,
+    ty: ty::Ty<'tcx>,
+    source: Source,
+) {
+    if ty.is_freeze(cx.tcx, cx.param_env, DUMMY_SP) || is_copy(cx, ty) {
+        // an UnsafeCell is !Copy, and an UnsafeCell is also the only type which
+        // is !Freeze, thus if our type is Copy we can be sure it must be Freeze
+        // as well.
+        return;
+    }
+
+    let (lint, msg, span) = source.lint();
+    span_lint_and_then(cx, lint, span, msg, |db| {
+        if in_macro(span) {
+            return; // Don't give suggestions into macros.
+        }
+        match source {
+            Source::Item { .. } => {
+                let const_kw_span = span.from_inner_byte_pos(0, 5);
+                db.span_suggestion_with_applicability(
+                    const_kw_span,
+                    "make this a static item",
+                    "static".to_string(),
+                    Applicability::MachineApplicable,
+                );
+            }
+            Source::Assoc { ty: ty_span, .. } => {
+                if ty.flags.contains(TypeFlags::HAS_FREE_LOCAL_NAMES) {
+                    db.span_help(ty_span, &format!("consider requiring `{}` to be `Copy`", ty));
+                }
+            }
+            Source::Expr { .. } => {
+                db.help(
+                    "assign this const to a local or static variable, and use the variable here",
+                );
+            }
+        }
+    });
+}
+
+
+pub struct NonCopyConst;
+
+impl LintPass for NonCopyConst {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(DECLARE_INTERIOR_MUTABLE_CONST, BORROW_INTERIOR_MUTABLE_CONST)
+    }
+}
+
+impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCopyConst {
+    fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, it: &'tcx Item) {
+        if let ItemConst(hir_ty, ..) = &it.node {
+            let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+            verify_ty_bound(cx, ty, Source::Item { item: it.span });
+        }
+    }
+
+    fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, trait_item: &'tcx TraitItem) {
+        if let TraitItemKind::Const(hir_ty, ..) = &trait_item.node {
+            let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+            verify_ty_bound(cx, ty, Source::Assoc { ty: hir_ty.span, item: trait_item.span });
+        }
+    }
+
+    fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, impl_item: &'tcx ImplItem) {
+        if let ImplItemKind::Const(hir_ty, ..) = &impl_item.node {
+            let item_node_id = cx.tcx.hir.get_parent_node(impl_item.id);
+            let item = cx.tcx.hir.expect_item(item_node_id);
+            // ensure the impl is an inherent impl.
+            if let ItemImpl(_, _, _, _, None, _, _) = item.node {
+                let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+                verify_ty_bound(cx, ty, Source::Assoc { ty: hir_ty.span, item: impl_item.span });
+            }
+        }
+    }
+
+    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
+        if let ExprPath(qpath) = &expr.node {
+            // Only lint if we use the const item inside a function.
+            if in_constant(cx, expr.id) {
+                return;
+            }
+
+            // make sure it is a const item.
+            match cx.tables.qpath_def(qpath, expr.hir_id) {
+                Def::Const(_) | Def::AssociatedConst(_) => {},
+                _ => return,
+            };
+
+            // climb up to resolve any field access and explicit referencing.
+            let mut cur_expr = expr;
+            let mut dereferenced_expr = expr;
+            let mut needs_check_adjustment = true;
+            loop {
+                let parent_id = cx.tcx.hir.get_parent_node(cur_expr.id);
+                if parent_id == cur_expr.id {
+                    break;
+                }
+                if let Some(map::NodeExpr(parent_expr)) = cx.tcx.hir.find(parent_id) {
+                    match &parent_expr.node {
+                        ExprAddrOf(..) => {
+                            // `&e` => `e` must be referenced
+                            needs_check_adjustment = false;
+                        }
+                        ExprField(..) => {
+                            dereferenced_expr = parent_expr;
+                            needs_check_adjustment = true;
+                        }
+                        ExprIndex(e, _) if ptr::eq(&**e, cur_expr) => {
+                            // `e[i]` => desugared to `*Index::index(&e, i)`,
+                            // meaning `e` must be referenced.
+                            // no need to go further up since a method call is involved now.
+                            needs_check_adjustment = false;
+                            break;
+                        }
+                        ExprUnary(UnDeref, _) => {
+                            // `*e` => desugared to `*Deref::deref(&e)`,
+                            // meaning `e` must be referenced.
+                            // no need to go further up since a method call is involved now.
+                            needs_check_adjustment = false;
+                            break;
+                        }
+                        _ => break,
+                    }
+                    cur_expr = parent_expr;
+                } else {
+                    break;
+                }
+            }
+
+            let ty = if !needs_check_adjustment {
+                cx.tables.expr_ty(dereferenced_expr)
+            } else {
+                let adjustments = cx.tables.expr_adjustments(dereferenced_expr);
+                if let Some(i) = adjustments.iter().position(|adj| match adj.kind {
+                    Adjust::Borrow(_) | Adjust::Deref(_) => true,
+                    _ => false,
+                }) {
+                    if i == 0 {
+                        cx.tables.expr_ty(dereferenced_expr)
+                    } else {
+                        adjustments[i - 1].target
+                    }
+                } else {
+                    // No borrow adjustments = the entire const is moved.
+                    return;
+                }
+            };
+
+            verify_ty_bound(cx, ty, Source::Expr { expr: expr.span });
+        }
+    }
+}
diff --git a/tests/ui/non_copy_const.rs b/tests/ui/non_copy_const.rs
new file mode 100644
index 00000000000..d7391577d23
--- /dev/null
+++ b/tests/ui/non_copy_const.rs
@@ -0,0 +1,147 @@
+#![feature(const_string_new, const_vec_new)]
+#![allow(ref_in_deref, dead_code)]
+
+use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering};
+use std::cell::Cell;
+use std::sync::Once;
+use std::borrow::Cow;
+use std::fmt::Display;
+
+const ATOMIC: AtomicUsize = AtomicUsize::new(5); //~ ERROR interior mutable
+const CELL: Cell<usize> = Cell::new(6); //~ ERROR interior mutable
+const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec<AtomicUsize>, u8) = ([ATOMIC], Vec::new(), 7);
+//~^ ERROR interior mutable
+
+macro_rules! declare_const {
+    ($name:ident: $ty:ty = $e:expr) => { const $name: $ty = $e; };
+}
+declare_const!(_ONCE: Once = Once::new()); //~ ERROR interior mutable
+
+// const ATOMIC_REF: &AtomicUsize = &AtomicUsize::new(7); // This will simply trigger E0492.
+
+const INTEGER: u8 = 8;
+const STRING: String = String::new();
+const STR: &str = "012345";
+const COW: Cow<str> = Cow::Borrowed("abcdef");
+//^ note: a const item of Cow is used in the `postgres` package.
+
+const NO_ANN: &Display = &70;
+
+static STATIC_TUPLE: (AtomicUsize, String) = (ATOMIC, STRING);
+//^ there should be no lints on this line
+
+#[allow(declare_interior_mutable_const)]
+const ONCE_INIT: Once = Once::new();
+
+trait Trait<T>: Copy {
+    type NonCopyType;
+
+    const ATOMIC: AtomicUsize; //~ ERROR interior mutable
+    const INTEGER: u64;
+    const STRING: String;
+    const SELF: Self; // (no error)
+    const INPUT: T;
+    //~^ ERROR interior mutable
+    //~| HELP consider requiring `T` to be `Copy`
+    const ASSOC: Self::NonCopyType;
+    //~^ ERROR interior mutable
+    //~| HELP consider requiring `<Self as Trait<T>>::NonCopyType` to be `Copy`
+
+    const AN_INPUT: T = Self::INPUT;
+    //~^ ERROR interior mutable
+    //~| ERROR consider requiring `T` to be `Copy`
+    declare_const!(ANOTHER_INPUT: T = Self::INPUT); //~ ERROR interior mutable
+}
+
+trait Trait2 {
+    type CopyType: Copy;
+
+    const SELF_2: Self;
+    //~^ ERROR interior mutable
+    //~| HELP consider requiring `Self` to be `Copy`
+    const ASSOC_2: Self::CopyType; // (no error)
+}
+
+// we don't lint impl of traits, because an impl has no power to change the interface.
+impl Trait<u32> for u64 {
+    type NonCopyType = u16;
+
+    const ATOMIC: AtomicUsize = AtomicUsize::new(9);
+    const INTEGER: u64 = 10;
+    const STRING: String = String::new();
+    const SELF: Self = 11;
+    const INPUT: u32 = 12;
+    const ASSOC: Self::NonCopyType = 13;
+}
+
+struct Local<T, U>(T, U);
+
+impl<T: Trait2 + Trait<u32>, U: Trait2> Local<T, U> {
+    const ASSOC_3: AtomicUsize = AtomicUsize::new(14); //~ ERROR interior mutable
+    const COW: Cow<'static, str> = Cow::Borrowed("tuvwxy");
+    const T_SELF: T = T::SELF_2;
+    const U_SELF: U = U::SELF_2;
+    //~^ ERROR interior mutable
+    //~| HELP consider requiring `U` to be `Copy`
+    const T_ASSOC: T::NonCopyType = T::ASSOC;
+    //~^ ERROR interior mutable
+    //~| HELP consider requiring `<T as Trait<u32>>::NonCopyType` to be `Copy`
+    const U_ASSOC: U::CopyType = U::ASSOC_2;
+}
+
+fn main() {
+    ATOMIC.store(1, Ordering::SeqCst); //~ ERROR interior mutability
+    assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); //~ ERROR interior mutability
+
+    ATOMIC_USIZE_INIT.store(2, Ordering::SeqCst); //~ ERROR interior mutability
+    assert_eq!(ATOMIC_USIZE_INIT.load(Ordering::SeqCst), 0); //~ ERROR interior mutability
+
+    let _once = ONCE_INIT;
+    let _once_ref = &ONCE_INIT; //~ ERROR interior mutability
+    let _once_ref_2 = &&ONCE_INIT; //~ ERROR interior mutability
+    let _once_ref_4 = &&&&ONCE_INIT; //~ ERROR interior mutability
+    let _once_mut = &mut ONCE_INIT; //~ ERROR interior mutability
+    let _atomic_into_inner = ATOMIC.into_inner();
+    // these should be all fine.
+    let _twice = (ONCE_INIT, ONCE_INIT);
+    let _ref_twice = &(ONCE_INIT, ONCE_INIT);
+    let _ref_once = &(ONCE_INIT, ONCE_INIT).0;
+    let _array_twice = [ONCE_INIT, ONCE_INIT];
+    let _ref_array_twice = &[ONCE_INIT, ONCE_INIT];
+    let _ref_array_once = &[ONCE_INIT, ONCE_INIT][0];
+
+    // referencing projection is still bad.
+    let _ = &ATOMIC_TUPLE; //~ ERROR interior mutability
+    let _ = &ATOMIC_TUPLE.0; //~ ERROR interior mutability
+    let _ = &(&&&&ATOMIC_TUPLE).0; //~ ERROR interior mutability
+    let _ = &ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
+    let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); //~ ERROR interior mutability
+    let _ = &*ATOMIC_TUPLE.1; //~ ERROR interior mutability
+    let _ = &ATOMIC_TUPLE.2;
+    let _ = (&&&&ATOMIC_TUPLE).0;
+    let _ = (&&&&ATOMIC_TUPLE).2;
+    let _ = ATOMIC_TUPLE.0;
+    let _ = ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
+    let _ = ATOMIC_TUPLE.1.into_iter();
+    let _ = ATOMIC_TUPLE.2;
+    let _ = &{ATOMIC_TUPLE};
+
+    CELL.set(2); //~ ERROR interior mutability
+    assert_eq!(CELL.get(), 6); //~ ERROR interior mutability
+
+    assert_eq!(INTEGER, 8);
+    assert!(STRING.is_empty());
+
+    let a = ATOMIC;
+    a.store(4, Ordering::SeqCst);
+    assert_eq!(a.load(Ordering::SeqCst), 4);
+
+    STATIC_TUPLE.0.store(3, Ordering::SeqCst);
+    assert_eq!(STATIC_TUPLE.0.load(Ordering::SeqCst), 3);
+    assert!(STATIC_TUPLE.1.is_empty());
+
+    u64::ATOMIC.store(5, Ordering::SeqCst); //~ ERROR interior mutability
+    assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); //~ ERROR interior mutability
+
+    assert_eq!(NO_ANN.to_string(), "70"); // should never lint this.
+}
diff --git a/tests/ui/non_copy_const.stderr b/tests/ui/non_copy_const.stderr
new file mode 100644
index 00000000000..388c7fabab0
--- /dev/null
+++ b/tests/ui/non_copy_const.stderr
@@ -0,0 +1,275 @@
+error: a const item should never be interior mutable
+  --> $DIR/non_copy_const.rs:10:1
+   |
+10 | const ATOMIC: AtomicUsize = AtomicUsize::new(5); //~ ERROR interior mutable
+   | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | |
+   | help: make this a static item: `static`
+   |
+   = note: #[deny(declare_interior_mutable_const)] on by default
+
+error: a const item should never be interior mutable
+  --> $DIR/non_copy_const.rs:11:1
+   |
+11 | const CELL: Cell<usize> = Cell::new(6); //~ ERROR interior mutable
+   | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | |
+   | help: make this a static item: `static`
+
+error: a const item should never be interior mutable
+  --> $DIR/non_copy_const.rs:12:1
+   |
+12 | const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec<AtomicUsize>, u8) = ([ATOMIC], Vec::new(), 7);
+   | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | |
+   | help: make this a static item: `static`
+
+error: a const item should never be interior mutable
+  --> $DIR/non_copy_const.rs:16:42
+   |
+16 |     ($name:ident: $ty:ty = $e:expr) => { const $name: $ty = $e; };
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^
+17 | }
+18 | declare_const!(_ONCE: Once = Once::new()); //~ ERROR interior mutable
+   | ------------------------------------------ in this macro invocation
+
+error: a const item should never be interior mutable
+  --> $DIR/non_copy_const.rs:39:5
+   |
+39 |     const ATOMIC: AtomicUsize; //~ ERROR interior mutable
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a const item should never be interior mutable
+  --> $DIR/non_copy_const.rs:43:5
+   |
+43 |     const INPUT: T;
+   |     ^^^^^^^^^^^^^^^
+   |
+help: consider requiring `T` to be `Copy`
+  --> $DIR/non_copy_const.rs:43:18
+   |
+43 |     const INPUT: T;
+   |                  ^
+
+error: a const item should never be interior mutable
+  --> $DIR/non_copy_const.rs:46:5
+   |
+46 |     const ASSOC: Self::NonCopyType;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider requiring `<Self as Trait<T>>::NonCopyType` to be `Copy`
+  --> $DIR/non_copy_const.rs:46:18
+   |
+46 |     const ASSOC: Self::NonCopyType;
+   |                  ^^^^^^^^^^^^^^^^^
+
+error: a const item should never be interior mutable
+  --> $DIR/non_copy_const.rs:50:5
+   |
+50 |     const AN_INPUT: T = Self::INPUT;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider requiring `T` to be `Copy`
+  --> $DIR/non_copy_const.rs:50:21
+   |
+50 |     const AN_INPUT: T = Self::INPUT;
+   |                     ^
+
+error: a const item should never be interior mutable
+  --> $DIR/non_copy_const.rs:16:42
+   |
+16 |     ($name:ident: $ty:ty = $e:expr) => { const $name: $ty = $e; };
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^
+...
+53 |     declare_const!(ANOTHER_INPUT: T = Self::INPUT); //~ ERROR interior mutable
+   |     ----------------------------------------------- in this macro invocation
+
+error: a const item should never be interior mutable
+  --> $DIR/non_copy_const.rs:59:5
+   |
+59 |     const SELF_2: Self;
+   |     ^^^^^^^^^^^^^^^^^^^
+   |
+help: consider requiring `Self` to be `Copy`
+  --> $DIR/non_copy_const.rs:59:19
+   |
+59 |     const SELF_2: Self;
+   |                   ^^^^
+
+error: a const item should never be interior mutable
+  --> $DIR/non_copy_const.rs:80:5
+   |
+80 |     const ASSOC_3: AtomicUsize = AtomicUsize::new(14); //~ ERROR interior mutable
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: a const item should never be interior mutable
+  --> $DIR/non_copy_const.rs:83:5
+   |
+83 |     const U_SELF: U = U::SELF_2;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider requiring `U` to be `Copy`
+  --> $DIR/non_copy_const.rs:83:19
+   |
+83 |     const U_SELF: U = U::SELF_2;
+   |                   ^
+
+error: a const item should never be interior mutable
+  --> $DIR/non_copy_const.rs:86:5
+   |
+86 |     const T_ASSOC: T::NonCopyType = T::ASSOC;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider requiring `<T as Trait<u32>>::NonCopyType` to be `Copy`
+  --> $DIR/non_copy_const.rs:86:20
+   |
+86 |     const T_ASSOC: T::NonCopyType = T::ASSOC;
+   |                    ^^^^^^^^^^^^^^
+
+error: a const item with interior mutability should not be borrowed
+  --> $DIR/non_copy_const.rs:93:5
+   |
+93 |     ATOMIC.store(1, Ordering::SeqCst); //~ ERROR interior mutability
+   |     ^^^^^^
+   |
+   = note: #[deny(borrow_interior_mutable_const)] on by default
+   = 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/non_copy_const.rs:94:16
+   |
+94 |     assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); //~ 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/non_copy_const.rs:96:5
+   |
+96 |     ATOMIC_USIZE_INIT.store(2, 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/non_copy_const.rs:97:16
+   |
+97 |     assert_eq!(ATOMIC_USIZE_INIT.load(Ordering::SeqCst), 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/non_copy_const.rs:100:22
+    |
+100 |     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/non_copy_const.rs:101:25
+    |
+101 |     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/non_copy_const.rs:102:27
+    |
+102 |     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/non_copy_const.rs:103:26
+    |
+103 |     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/non_copy_const.rs:114:14
+    |
+114 |     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/non_copy_const.rs:115:14
+    |
+115 |     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/non_copy_const.rs:116:19
+    |
+116 |     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/non_copy_const.rs:117:14
+    |
+117 |     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/non_copy_const.rs:118:13
+    |
+118 |     let _ = ATOMIC_TUPLE.0[0].load(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/non_copy_const.rs:124:13
+    |
+124 |     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/non_copy_const.rs:129:5
+    |
+129 |     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/non_copy_const.rs:130:16
+    |
+130 |     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/non_copy_const.rs:143:5
+    |
+143 |     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/non_copy_const.rs:144:16
+    |
+144 |     assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); //~ ERROR interior mutability
+    |                ^^^^^^^^^^^
+    |
+    = help: assign this const to a local or static variable, and use the variable here
+
+error: aborting due to 31 previous errors
+