mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 23:24:24 +00:00
Change the criteria of interior_mutable_const
* stop linting associated types and generic type parameters * start linting ones in trait impls whose corresponding definitions in the traits are generic * remove the `is_copy` check as presumably the only purpose of it is to allow generics with `Copy` bounds as `Freeze` is internal and generics are no longer linted * remove the term 'copy' from the tests as being `Copy` no longer have meaning
This commit is contained in:
parent
5af88e3c2d
commit
d655c0a938
5 changed files with 159 additions and 128 deletions
|
@ -6,14 +6,17 @@ use std::ptr;
|
|||
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind, UnOp};
|
||||
use rustc_infer::traits::specialization_graph;
|
||||
use rustc_lint::{LateContext, LateLintPass, Lint};
|
||||
use rustc_middle::ty::adjustment::Adjust;
|
||||
use rustc_middle::ty::{Ty, TypeFlags};
|
||||
use rustc_middle::ty::fold::TypeFoldable as _;
|
||||
use rustc_middle::ty::{AssocKind, Ty, TypeFlags};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::{InnerSpan, Span, DUMMY_SP};
|
||||
use rustc_typeck::hir_ty_to_ty;
|
||||
|
||||
use crate::utils::{in_constant, is_copy, qpath_res, span_lint_and_then};
|
||||
use crate::utils::{in_constant, qpath_res, span_lint_and_then};
|
||||
use if_chain::if_chain;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for declaration of `const` items which is interior
|
||||
|
@ -83,11 +86,10 @@ declare_clippy_lint! {
|
|||
"referencing `const` with interior mutability"
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Copy, Clone)]
|
||||
enum Source {
|
||||
Item { item: Span },
|
||||
Assoc { item: Span, ty: Span },
|
||||
Assoc { item: Span },
|
||||
Expr { expr: Span },
|
||||
}
|
||||
|
||||
|
@ -110,10 +112,15 @@ impl Source {
|
|||
}
|
||||
|
||||
fn verify_ty_bound<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, source: Source) {
|
||||
if ty.is_freeze(cx.tcx.at(DUMMY_SP), cx.param_env) || 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.
|
||||
// Ignore types whose layout is unknown since `is_freeze` reports every generic types as `!Freeze`,
|
||||
// making it indistinguishable from `UnsafeCell`. i.e. it isn't a tool to prove a type is
|
||||
// 'unfrozen'. However, this code causes a false negative in which
|
||||
// a type contains a layout-unknown type, but also a unsafe cell like `const CELL: Cell<T>`.
|
||||
// Yet, it's better than `ty.has_type_flags(TypeFlags::HAS_TY_PARAM | TypeFlags::HAS_PROJECTION)`
|
||||
// since it works when a pointer indirection involves (`Cell<*const T>`).
|
||||
// Making up a `ParamEnv` where every generic params and assoc types are `Freeze`is another option;
|
||||
// but I'm not sure whether it's a decent way, if possible.
|
||||
if cx.tcx.layout_of(cx.param_env.and(ty)).is_err() || ty.is_freeze(cx.tcx.at(DUMMY_SP), cx.param_env) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -127,11 +134,7 @@ fn verify_ty_bound<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, source: Source) {
|
|||
let const_kw_span = span.from_inner(InnerSpan::new(0, 5));
|
||||
diag.span_label(const_kw_span, "make this a static item (maybe with lazy_static)");
|
||||
},
|
||||
Source::Assoc { ty: ty_span, .. } => {
|
||||
if ty.flags().intersects(TypeFlags::HAS_FREE_LOCAL_NAMES) {
|
||||
diag.span_label(ty_span, &format!("consider requiring `{}` to be `Copy`", ty));
|
||||
}
|
||||
},
|
||||
Source::Assoc { .. } => (),
|
||||
Source::Expr { .. } => {
|
||||
diag.help("assign this const to a local or static variable, and use the variable here");
|
||||
},
|
||||
|
@ -152,14 +155,10 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
|
|||
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx TraitItem<'_>) {
|
||||
if let TraitItemKind::Const(hir_ty, ..) = &trait_item.kind {
|
||||
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,
|
||||
},
|
||||
);
|
||||
// Normalize assoc types because ones originated from generic params
|
||||
// bounded other traits could have their bound.
|
||||
let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
|
||||
verify_ty_bound(cx, normalized, Source::Assoc { item: trait_item.span });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,17 +166,47 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
|
|||
if let ImplItemKind::Const(hir_ty, ..) = &impl_item.kind {
|
||||
let item_hir_id = cx.tcx.hir().get_parent_node(impl_item.hir_id);
|
||||
let item = cx.tcx.hir().expect_item(item_hir_id);
|
||||
// Ensure the impl is an inherent impl.
|
||||
if let ItemKind::Impl { of_trait: None, .. } = item.kind {
|
||||
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,
|
||||
},
|
||||
);
|
||||
|
||||
match &item.kind {
|
||||
ItemKind::Impl {
|
||||
of_trait: Some(of_trait_ref),
|
||||
..
|
||||
} => {
|
||||
if_chain! {
|
||||
// Lint a trait impl item only when the definition is a generic type,
|
||||
// assuming a assoc const is not meant to be a interior mutable type.
|
||||
if let Some(of_trait_def_id) = of_trait_ref.trait_def_id();
|
||||
if let Some(of_assoc_item) = specialization_graph::Node::Trait(of_trait_def_id)
|
||||
.item(cx.tcx, impl_item.ident, AssocKind::Const, of_trait_def_id);
|
||||
if cx.tcx
|
||||
// Normalize assoc types because ones originated from generic params
|
||||
// bounded other traits could have their bound at the trait defs;
|
||||
// and, in that case, the definition is *not* generic.
|
||||
.normalize_erasing_regions(
|
||||
cx.tcx.param_env(of_trait_def_id),
|
||||
cx.tcx.type_of(of_assoc_item.def_id),
|
||||
)
|
||||
.has_type_flags(TypeFlags::HAS_PROJECTION | TypeFlags::HAS_TY_PARAM);
|
||||
then {
|
||||
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
|
||||
let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
|
||||
verify_ty_bound(
|
||||
cx,
|
||||
normalized,
|
||||
Source::Assoc {
|
||||
item: impl_item.span,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
ItemKind::Impl { of_trait: None, .. } => {
|
||||
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
|
||||
// Normalize assoc types originated from generic params.
|
||||
let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
|
||||
verify_ty_bound(cx, normalized, Source::Assoc { item: impl_item.span });
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,16 +19,30 @@ const NO_ANN: &dyn Display = &70;
|
|||
static STATIC_TUPLE: (AtomicUsize, String) = (ATOMIC, STRING);
|
||||
const ONCE_INIT: Once = Once::new();
|
||||
|
||||
trait Trait<T>: Copy {
|
||||
type NonCopyType;
|
||||
trait Trait<T> {
|
||||
type AssocType;
|
||||
|
||||
const ATOMIC: AtomicUsize;
|
||||
const INPUT: T;
|
||||
const ASSOC: Self::AssocType;
|
||||
|
||||
fn function() {
|
||||
let _ = &Self::INPUT;
|
||||
let _ = &Self::ASSOC;
|
||||
}
|
||||
}
|
||||
|
||||
impl Trait<u32> for u64 {
|
||||
type NonCopyType = u16;
|
||||
type AssocType = AtomicUsize;
|
||||
|
||||
const ATOMIC: AtomicUsize = AtomicUsize::new(9);
|
||||
const INPUT: u32 = 10;
|
||||
const ASSOC: Self::AssocType = AtomicUsize::new(11);
|
||||
|
||||
fn function() {
|
||||
let _ = &Self::INPUT;
|
||||
let _ = &Self::ASSOC; //~ ERROR interior mutability
|
||||
}
|
||||
}
|
||||
|
||||
// This is just a pointer that can be safely dereferended,
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
error: a `const` item with interior mutability should not be borrowed
|
||||
--> $DIR/borrow_interior_mutable_const.rs:66:5
|
||||
--> $DIR/borrow_interior_mutable_const.rs:44:18
|
||||
|
|
||||
LL | ATOMIC.store(1, Ordering::SeqCst); //~ ERROR interior mutability
|
||||
| ^^^^^^
|
||||
LL | let _ = &Self::ASSOC; //~ ERROR interior mutability
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings`
|
||||
= 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:16
|
||||
--> $DIR/borrow_interior_mutable_const.rs:80:5
|
||||
|
|
||||
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:81:16
|
||||
|
|
||||
LL | assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); //~ ERROR interior mutability
|
||||
| ^^^^^^
|
||||
|
@ -16,7 +24,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:70:22
|
||||
--> $DIR/borrow_interior_mutable_const.rs:84:22
|
||||
|
|
||||
LL | let _once_ref = &ONCE_INIT; //~ ERROR interior mutability
|
||||
| ^^^^^^^^^
|
||||
|
@ -24,7 +32,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:71:25
|
||||
--> $DIR/borrow_interior_mutable_const.rs:85:25
|
||||
|
|
||||
LL | let _once_ref_2 = &&ONCE_INIT; //~ ERROR interior mutability
|
||||
| ^^^^^^^^^
|
||||
|
@ -32,7 +40,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:72:27
|
||||
--> $DIR/borrow_interior_mutable_const.rs:86:27
|
||||
|
|
||||
LL | let _once_ref_4 = &&&&ONCE_INIT; //~ ERROR interior mutability
|
||||
| ^^^^^^^^^
|
||||
|
@ -40,7 +48,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:73:26
|
||||
--> $DIR/borrow_interior_mutable_const.rs:87:26
|
||||
|
|
||||
LL | let _once_mut = &mut ONCE_INIT; //~ ERROR interior mutability
|
||||
| ^^^^^^^^^
|
||||
|
@ -48,7 +56,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:84:14
|
||||
--> $DIR/borrow_interior_mutable_const.rs:98:14
|
||||
|
|
||||
LL | let _ = &ATOMIC_TUPLE; //~ ERROR interior mutability
|
||||
| ^^^^^^^^^^^^
|
||||
|
@ -56,7 +64,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:85:14
|
||||
--> $DIR/borrow_interior_mutable_const.rs:99:14
|
||||
|
|
||||
LL | let _ = &ATOMIC_TUPLE.0; //~ ERROR interior mutability
|
||||
| ^^^^^^^^^^^^
|
||||
|
@ -64,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:86:19
|
||||
--> $DIR/borrow_interior_mutable_const.rs:100:19
|
||||
|
|
||||
LL | let _ = &(&&&&ATOMIC_TUPLE).0; //~ ERROR interior mutability
|
||||
| ^^^^^^^^^^^^
|
||||
|
@ -72,7 +80,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:87:14
|
||||
--> $DIR/borrow_interior_mutable_const.rs:101:14
|
||||
|
|
||||
LL | let _ = &ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
|
||||
| ^^^^^^^^^^^^
|
||||
|
@ -80,7 +88,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:88:13
|
||||
--> $DIR/borrow_interior_mutable_const.rs:102:13
|
||||
|
|
||||
LL | let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); //~ ERROR interior mutability
|
||||
| ^^^^^^^^^^^^
|
||||
|
@ -88,7 +96,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:94:13
|
||||
--> $DIR/borrow_interior_mutable_const.rs:108:13
|
||||
|
|
||||
LL | let _ = ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
|
||||
| ^^^^^^^^^^^^
|
||||
|
@ -96,7 +104,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:99:5
|
||||
--> $DIR/borrow_interior_mutable_const.rs:113:5
|
||||
|
|
||||
LL | CELL.set(2); //~ ERROR interior mutability
|
||||
| ^^^^
|
||||
|
@ -104,7 +112,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:100:16
|
||||
--> $DIR/borrow_interior_mutable_const.rs:114:16
|
||||
|
|
||||
LL | assert_eq!(CELL.get(), 6); //~ ERROR interior mutability
|
||||
| ^^^^
|
||||
|
@ -112,7 +120,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:113:5
|
||||
--> $DIR/borrow_interior_mutable_const.rs:127:5
|
||||
|
|
||||
LL | u64::ATOMIC.store(5, Ordering::SeqCst); //~ ERROR interior mutability
|
||||
| ^^^^^^^^^^^
|
||||
|
@ -120,12 +128,12 @@ 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:114:16
|
||||
--> $DIR/borrow_interior_mutable_const.rs:128:16
|
||||
|
|
||||
LL | 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 16 previous errors
|
||||
error: aborting due to 17 previous errors
|
||||
|
||||
|
|
|
@ -34,60 +34,64 @@ static STATIC_TUPLE: (AtomicUsize, String) = (ATOMIC, STRING);
|
|||
#[allow(clippy::declare_interior_mutable_const)]
|
||||
const ONCE_INIT: Once = Once::new();
|
||||
|
||||
trait Trait<T>: Copy {
|
||||
type NonCopyType;
|
||||
struct Wrapper<T>(T);
|
||||
|
||||
trait Trait<T: Trait2<AssocType5 = AtomicUsize>> {
|
||||
type AssocType;
|
||||
type AssocType2;
|
||||
type AssocType3;
|
||||
|
||||
const ATOMIC: AtomicUsize; //~ ERROR interior mutable
|
||||
const INTEGER: u64;
|
||||
const STRING: String;
|
||||
const SELF: Self; // (no error)
|
||||
const SELF: Self;
|
||||
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 INPUT_ASSOC: T::AssocType4;
|
||||
const INPUT_ASSOC_2: T::AssocType5; //~ ERROR interior mutable
|
||||
const ASSOC: Self::AssocType;
|
||||
const ASSOC_2: Self::AssocType2;
|
||||
const WRAPPED_ASSOC_2: Wrapper<Self::AssocType2>;
|
||||
const WRAPPED_ASSOC_3: Wrapper<Self::AssocType3>;
|
||||
|
||||
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
|
||||
declare_const!(ANOTHER_INPUT: T = Self::INPUT);
|
||||
declare_const!(ANOTHER_ATOMIC: AtomicUsize = Self::ATOMIC); //~ ERROR interior mutable
|
||||
}
|
||||
|
||||
trait Trait2 {
|
||||
type CopyType: Copy;
|
||||
type AssocType4;
|
||||
type AssocType5;
|
||||
|
||||
const SELF_2: Self;
|
||||
//~^ ERROR interior mutable
|
||||
//~| HELP consider requiring `Self` to be `Copy`
|
||||
const ASSOC_2: Self::CopyType; // (no error)
|
||||
const ASSOC_4: Self::AssocType4;
|
||||
}
|
||||
|
||||
// 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;
|
||||
impl<T: Trait2<AssocType5 = AtomicUsize>> Trait<T> for u64 {
|
||||
type AssocType = u16;
|
||||
type AssocType2 = AtomicUsize;
|
||||
type AssocType3 = T;
|
||||
|
||||
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;
|
||||
const INPUT: T = T::SELF_2;
|
||||
const INPUT_ASSOC: T::AssocType4 = T::ASSOC_4;
|
||||
const INPUT_ASSOC_2: T::AssocType5 = AtomicUsize::new(16);
|
||||
const ASSOC: Self::AssocType = 13;
|
||||
const ASSOC_2: Self::AssocType2 = AtomicUsize::new(15); //~ ERROR interior mutable
|
||||
const WRAPPED_ASSOC_2: Wrapper<Self::AssocType2> = Wrapper(AtomicUsize::new(16)); //~ ERROR interior mutable
|
||||
const WRAPPED_ASSOC_3: Wrapper<Self::AssocType3> = Wrapper(T::SELF_2);
|
||||
}
|
||||
|
||||
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
|
||||
impl<T: Trait<U>, U: Trait2<AssocType5 = AtomicUsize>> Local<T, U> {
|
||||
const ASSOC_5: 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;
|
||||
const T_ASSOC: T::AssocType = T::ASSOC;
|
||||
const U_ASSOC: U::AssocType5 = AtomicUsize::new(17); //~ ERROR interior mutable
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -36,34 +36,16 @@ LL | declare_const!(_ONCE: Once = Once::new()); //~ ERROR interior mutable
|
|||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: a `const` item should never be interior mutable
|
||||
--> $DIR/declare_interior_mutable_const.rs:40:5
|
||||
--> $DIR/declare_interior_mutable_const.rs:44:5
|
||||
|
|
||||
LL | const ATOMIC: AtomicUsize; //~ ERROR interior mutable
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: a `const` item should never be interior mutable
|
||||
--> $DIR/declare_interior_mutable_const.rs:44:5
|
||||
--> $DIR/declare_interior_mutable_const.rs:50:5
|
||||
|
|
||||
LL | const INPUT: T;
|
||||
| ^^^^^^^^^^^^^-^
|
||||
| |
|
||||
| consider requiring `T` to be `Copy`
|
||||
|
||||
error: a `const` item should never be interior mutable
|
||||
--> $DIR/declare_interior_mutable_const.rs:47:5
|
||||
|
|
||||
LL | const ASSOC: Self::NonCopyType;
|
||||
| ^^^^^^^^^^^^^-----------------^
|
||||
| |
|
||||
| consider requiring `<Self as Trait<T>>::NonCopyType` to be `Copy`
|
||||
|
||||
error: a `const` item should never be interior mutable
|
||||
--> $DIR/declare_interior_mutable_const.rs:51:5
|
||||
|
|
||||
LL | const AN_INPUT: T = Self::INPUT;
|
||||
| ^^^^^^^^^^^^^^^^-^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| consider requiring `T` to be `Copy`
|
||||
LL | const INPUT_ASSOC_2: T::AssocType5; //~ ERROR interior mutable
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: a `const` item should never be interior mutable
|
||||
--> $DIR/declare_interior_mutable_const.rs:16:9
|
||||
|
@ -71,40 +53,34 @@ error: a `const` item should never be interior mutable
|
|||
LL | const $name: $ty = $e;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
...
|
||||
LL | declare_const!(ANOTHER_INPUT: T = Self::INPUT); //~ ERROR interior mutable
|
||||
| ----------------------------------------------- in this macro invocation
|
||||
LL | declare_const!(ANOTHER_ATOMIC: AtomicUsize = Self::ATOMIC); //~ ERROR interior mutable
|
||||
| ----------------------------------------------------------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: a `const` item should never be interior mutable
|
||||
--> $DIR/declare_interior_mutable_const.rs:60:5
|
||||
--> $DIR/declare_interior_mutable_const.rs:82:5
|
||||
|
|
||||
LL | const SELF_2: Self;
|
||||
| ^^^^^^^^^^^^^^----^
|
||||
| |
|
||||
| consider requiring `Self` to be `Copy`
|
||||
LL | const ASSOC_2: Self::AssocType2 = AtomicUsize::new(15); //~ ERROR interior mutable
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: a `const` item should never be interior mutable
|
||||
--> $DIR/declare_interior_mutable_const.rs:81:5
|
||||
--> $DIR/declare_interior_mutable_const.rs:83:5
|
||||
|
|
||||
LL | const ASSOC_3: AtomicUsize = AtomicUsize::new(14); //~ ERROR interior mutable
|
||||
LL | const WRAPPED_ASSOC_2: Wrapper<Self::AssocType2> = Wrapper(AtomicUsize::new(16)); //~ ERROR interior mutable
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: a `const` item should never be interior mutable
|
||||
--> $DIR/declare_interior_mutable_const.rs:90:5
|
||||
|
|
||||
LL | const ASSOC_5: AtomicUsize = AtomicUsize::new(14); //~ ERROR interior mutable
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: a `const` item should never be interior mutable
|
||||
--> $DIR/declare_interior_mutable_const.rs:84:5
|
||||
--> $DIR/declare_interior_mutable_const.rs:94:5
|
||||
|
|
||||
LL | const U_SELF: U = U::SELF_2;
|
||||
| ^^^^^^^^^^^^^^-^^^^^^^^^^^^^
|
||||
| |
|
||||
| consider requiring `U` to be `Copy`
|
||||
LL | const U_ASSOC: U::AssocType5 = AtomicUsize::new(17); //~ ERROR interior mutable
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: a `const` item should never be interior mutable
|
||||
--> $DIR/declare_interior_mutable_const.rs:87:5
|
||||
|
|
||||
LL | const T_ASSOC: T::NonCopyType = T::ASSOC;
|
||||
| ^^^^^^^^^^^^^^^--------------^^^^^^^^^^^^
|
||||
| |
|
||||
| consider requiring `<T as Trait<u32>>::NonCopyType` to be `Copy`
|
||||
|
||||
error: aborting due to 13 previous errors
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
|
|
Loading…
Reference in a new issue