Skip to content

Commit

Permalink
borrow_interior_mutable_const ICE into FN (#13877)
Browse files Browse the repository at this point in the history
This PR just makes sure that we exit the function before getting an ICE
and adds a regression test. Related to #12979. We would need to keep
researching the issue, but as the ICEing code isn't that complicated,
getting a hotfix into nightly is urgent.

changelog:[`borrow_interior_mutable_const`] Fix ICE #12979
  • Loading branch information
xFrednet authored Dec 29, 2024
2 parents c8ba3e1 + d7cc6c4 commit f5f1abd
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 19 deletions.
11 changes: 6 additions & 5 deletions clippy_lints/src/non_copy_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ impl<'tcx> NonCopyConst<'tcx> {
}

fn is_value_unfrozen_raw_inner(cx: &LateContext<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> bool {
// No branch that we check (yet) should continue if val isn't a ValTree::Branch
let ty::ValTree::Branch(val) = val else { return false };
match *ty.kind() {
// the fact that we have to dig into every structs to search enums
// leads us to the point checking `UnsafeCell` directly is the only option.
Expand All @@ -197,12 +199,13 @@ impl<'tcx> NonCopyConst<'tcx> {
// contained value.
ty::Adt(def, ..) if def.is_union() => false,
ty::Array(ty, _) => val
.unwrap_branch()
.iter()
.any(|field| Self::is_value_unfrozen_raw_inner(cx, *field, ty)),
ty::Adt(def, args) if def.is_enum() => {
let (&variant_index, fields) = val.unwrap_branch().split_first().unwrap();
let variant_index = VariantIdx::from_u32(variant_index.unwrap_leaf().to_u32());
let Some((&ty::ValTree::Leaf(variant_index), fields)) = val.split_first() else {
return false;
};
let variant_index = VariantIdx::from_u32(variant_index.to_u32());
fields
.iter()
.copied()
Expand All @@ -215,12 +218,10 @@ impl<'tcx> NonCopyConst<'tcx> {
.any(|(field, ty)| Self::is_value_unfrozen_raw_inner(cx, field, ty))
},
ty::Adt(def, args) => val
.unwrap_branch()
.iter()
.zip(def.non_enum_variant().fields.iter().map(|field| field.ty(cx.tcx, args)))
.any(|(field, ty)| Self::is_value_unfrozen_raw_inner(cx, *field, ty)),
ty::Tuple(tys) => val
.unwrap_branch()
.iter()
.zip(tys)
.any(|(field, ty)| Self::is_value_unfrozen_raw_inner(cx, *field, ty)),
Expand Down
11 changes: 11 additions & 0 deletions tests/ui/borrow_interior_mutable_const/others.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@ impl<T> std::ops::Deref for StaticRef<T> {
}
}

// ICE regression test
mod issue12979 {
use std::cell::UnsafeCell;

const ATOMIC_TUPLE: (Vec<UnsafeCell<u8>>, ()) = (Vec::new(), ());

fn main() {
let _x = &ATOMIC_TUPLE.0;
}
}

// 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()) };

Expand Down
28 changes: 14 additions & 14 deletions tests/ui/borrow_interior_mutable_const/others.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: a `const` item with interior mutability should not be borrowed
--> tests/ui/borrow_interior_mutable_const/others.rs:54:5
--> tests/ui/borrow_interior_mutable_const/others.rs:65:5
|
LL | ATOMIC.store(1, Ordering::SeqCst);
| ^^^^^^
Expand All @@ -12,103 +12,103 @@ LL | #![deny(clippy::borrow_interior_mutable_const)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: a `const` item with interior mutability should not be borrowed
--> tests/ui/borrow_interior_mutable_const/others.rs:55:16
--> tests/ui/borrow_interior_mutable_const/others.rs:66:16
|
LL | assert_eq!(ATOMIC.load(Ordering::SeqCst), 5);
| ^^^^^^
|
= 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
--> tests/ui/borrow_interior_mutable_const/others.rs:58:22
--> tests/ui/borrow_interior_mutable_const/others.rs:69:22
|
LL | let _once_ref = &ONCE_INIT;
| ^^^^^^^^^
|
= 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
--> tests/ui/borrow_interior_mutable_const/others.rs:59:25
--> tests/ui/borrow_interior_mutable_const/others.rs:70:25
|
LL | let _once_ref_2 = &&ONCE_INIT;
| ^^^^^^^^^
|
= 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
--> tests/ui/borrow_interior_mutable_const/others.rs:60:27
--> tests/ui/borrow_interior_mutable_const/others.rs:71:27
|
LL | let _once_ref_4 = &&&&ONCE_INIT;
| ^^^^^^^^^
|
= 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
--> tests/ui/borrow_interior_mutable_const/others.rs:61:26
--> tests/ui/borrow_interior_mutable_const/others.rs:72:26
|
LL | let _once_mut = &mut ONCE_INIT;
| ^^^^^^^^^
|
= 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
--> tests/ui/borrow_interior_mutable_const/others.rs:72:14
--> tests/ui/borrow_interior_mutable_const/others.rs:83:14
|
LL | let _ = &ATOMIC_TUPLE;
| ^^^^^^^^^^^^
|
= 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
--> tests/ui/borrow_interior_mutable_const/others.rs:73:14
--> tests/ui/borrow_interior_mutable_const/others.rs:84:14
|
LL | let _ = &ATOMIC_TUPLE.0;
| ^^^^^^^^^^^^
|
= 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
--> tests/ui/borrow_interior_mutable_const/others.rs:74:19
--> tests/ui/borrow_interior_mutable_const/others.rs:85:19
|
LL | let _ = &(&&&&ATOMIC_TUPLE).0;
| ^^^^^^^^^^^^
|
= 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
--> tests/ui/borrow_interior_mutable_const/others.rs:75:14
--> tests/ui/borrow_interior_mutable_const/others.rs:86:14
|
LL | let _ = &ATOMIC_TUPLE.0[0];
| ^^^^^^^^^^^^
|
= 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
--> tests/ui/borrow_interior_mutable_const/others.rs:76:13
--> tests/ui/borrow_interior_mutable_const/others.rs:87:13
|
LL | let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst);
| ^^^^^^^^^^^^
|
= 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
--> tests/ui/borrow_interior_mutable_const/others.rs:81:13
--> tests/ui/borrow_interior_mutable_const/others.rs:92:13
|
LL | let _ = ATOMIC_TUPLE.0[0];
| ^^^^^^^^^^^^
|
= 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
--> tests/ui/borrow_interior_mutable_const/others.rs:86:5
--> tests/ui/borrow_interior_mutable_const/others.rs:97:5
|
LL | CELL.set(2);
| ^^^^
|
= 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
--> tests/ui/borrow_interior_mutable_const/others.rs:87:16
--> tests/ui/borrow_interior_mutable_const/others.rs:98:16
|
LL | assert_eq!(CELL.get(), 6);
| ^^^^
Expand Down

0 comments on commit f5f1abd

Please sign in to comment.