Skip to content

Commit

Permalink
Resolve projections during internal mutability analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
GrigorenkoPV committed Jan 31, 2025
1 parent d79f862 commit 58d4834
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 0 deletions.
6 changes: 6 additions & 0 deletions clippy_lints/src/non_copy_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ impl<'tcx> NonCopyConst<'tcx> {
.iter()
.zip(tys)
.any(|(field, ty)| Self::is_value_unfrozen_raw_inner(cx, *field, ty)),
ty::Alias(ty::Projection, _) => match cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty) {
Ok(normalized_ty) if ty != normalized_ty => {
Self::is_value_unfrozen_raw_inner(cx, ty::ValTree::Branch(val), normalized_ty)
},
_ => false,
},
_ => false,
}
}
Expand Down
4 changes: 4 additions & 0 deletions clippy_utils/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1227,6 +1227,10 @@ impl<'tcx> InteriorMut<'tcx> {
.find_map(|f| self.interior_mut_ty_chain(cx, f.ty(cx.tcx, args)))
}
},
ty::Alias(ty::Projection, _) => match cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty) {
Ok(normalized_ty) if ty != normalized_ty => self.interior_mut_ty_chain(cx, normalized_ty),
_ => None,
},
_ => None,
};

Expand Down
42 changes: 42 additions & 0 deletions tests/ui/borrow_interior_mutable_const/projections.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#![deny(clippy::borrow_interior_mutable_const)]
#![deny(clippy::declare_interior_mutable_const)]

// Inspired by https://github.com/rust-lang/rust/pull/130543#issuecomment-2364828139

use std::cell::UnsafeCell;

trait Trait {
type Assoc;
}

type Assoc<T> = <T as Trait>::Assoc;

impl Trait for u8 {
type Assoc = UnsafeCell<u8>;
}

impl Trait for () {
type Assoc = ();
}

enum MaybeMutable {
Mutable(Assoc<u8>),
Immutable(Assoc<()>),
}

const CELL: Assoc<u8> = UnsafeCell::new(0); //~ ERROR: interior mutable
const UNIT: Assoc<()> = ();
const MUTABLE: MaybeMutable = MaybeMutable::Mutable(CELL); //~ ERROR: interior mutable
const IMMUTABLE: MaybeMutable = MaybeMutable::Immutable(UNIT);

fn print_ref<T>(t: &T) {
let p: *const T = t;
println!("{p:p}")
}

fn main() {
print_ref(&CELL); //~ ERROR: interior mutability
print_ref(&UNIT);
print_ref(&MUTABLE); //~ ERROR: interior mutability
print_ref(&IMMUTABLE);
}
44 changes: 44 additions & 0 deletions tests/ui/borrow_interior_mutable_const/projections.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
error: a `const` item should not be interior mutable
--> tests/ui/borrow_interior_mutable_const/projections.rs:27:1
|
LL | const CELL: Assoc<u8> = UnsafeCell::new(0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider making this `Sync` so that it can go in a static item or using a `thread_local`
note: the lint level is defined here
--> tests/ui/borrow_interior_mutable_const/projections.rs:2:9
|
LL | #![deny(clippy::declare_interior_mutable_const)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: a `const` item should not be interior mutable
--> tests/ui/borrow_interior_mutable_const/projections.rs:29:1
|
LL | const MUTABLE: MaybeMutable = MaybeMutable::Mutable(CELL);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider making this `Sync` so that it can go in a static item or using a `thread_local`

error: a `const` item with interior mutability should not be borrowed
--> tests/ui/borrow_interior_mutable_const/projections.rs:38:16
|
LL | print_ref(&CELL);
| ^^^^
|
= help: assign this const to a local or static variable, and use the variable here
note: the lint level is defined here
--> tests/ui/borrow_interior_mutable_const/projections.rs:1:9
|
LL | #![deny(clippy::borrow_interior_mutable_const)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: a `const` item with interior mutability should not be borrowed
--> tests/ui/borrow_interior_mutable_const/projections.rs:40:16
|
LL | print_ref(&MUTABLE);
| ^^^^^^^
|
= help: assign this const to a local or static variable, and use the variable here

error: aborting due to 4 previous errors

0 comments on commit 58d4834

Please sign in to comment.