Skip to content

Commit f92b587

Browse files
committed
borrow_interior_mutable_const ICE into FN
Convert the ICE reported in #12979 into a false negative. We prefer a false negative to a ICE (because the ICE could still affect the user even when not activating the lint).
1 parent 592fd34 commit f92b587

File tree

3 files changed

+31
-19
lines changed

3 files changed

+31
-19
lines changed

clippy_lints/src/non_copy_const.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ impl<'tcx> NonCopyConst<'tcx> {
189189
}
190190

191191
fn is_value_unfrozen_raw_inner(cx: &LateContext<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> bool {
192+
// No branch that we check (yet) should continue if val isn't a ValTree::Branch
193+
let ty::ValTree::Branch(val) = val else { return false };
192194
match *ty.kind() {
193195
// the fact that we have to dig into every structs to search enums
194196
// leads us to the point checking `UnsafeCell` directly is the only option.
@@ -197,12 +199,13 @@ impl<'tcx> NonCopyConst<'tcx> {
197199
// contained value.
198200
ty::Adt(def, ..) if def.is_union() => false,
199201
ty::Array(ty, _) => val
200-
.unwrap_branch()
201202
.iter()
202203
.any(|field| Self::is_value_unfrozen_raw_inner(cx, *field, ty)),
203204
ty::Adt(def, args) if def.is_enum() => {
204-
let (&variant_index, fields) = val.unwrap_branch().split_first().unwrap();
205-
let variant_index = VariantIdx::from_u32(variant_index.unwrap_leaf().to_u32());
205+
let (&ty::ValTree::Leaf(variant_index), fields) = val.split_first().unwrap() else {
206+
return false;
207+
};
208+
let variant_index = VariantIdx::from_u32(variant_index.to_u32());
206209
fields
207210
.iter()
208211
.copied()
@@ -215,12 +218,10 @@ impl<'tcx> NonCopyConst<'tcx> {
215218
.any(|(field, ty)| Self::is_value_unfrozen_raw_inner(cx, field, ty))
216219
},
217220
ty::Adt(def, args) => val
218-
.unwrap_branch()
219221
.iter()
220222
.zip(def.non_enum_variant().fields.iter().map(|field| field.ty(cx.tcx, args)))
221223
.any(|(field, ty)| Self::is_value_unfrozen_raw_inner(cx, *field, ty)),
222224
ty::Tuple(tys) => val
223-
.unwrap_branch()
224225
.iter()
225226
.zip(tys)
226227
.any(|(field, ty)| Self::is_value_unfrozen_raw_inner(cx, *field, ty)),

tests/ui/borrow_interior_mutable_const/others.rs

+11
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ impl<T> std::ops::Deref for StaticRef<T> {
4747
}
4848
}
4949

50+
// ICE regression test
51+
mod issue12979 {
52+
use std::cell::UnsafeCell;
53+
54+
const ATOMIC_TUPLE: (Vec<UnsafeCell<u8>>, ()) = (Vec::new(), ());
55+
56+
fn main() {
57+
let _x = &ATOMIC_TUPLE.0;
58+
}
59+
}
60+
5061
// use a tuple to make sure referencing a field behind a pointer isn't linted.
5162
const CELL_REF: StaticRef<(UnsafeCell<u32>,)> = unsafe { StaticRef::new(std::ptr::null()) };
5263

tests/ui/borrow_interior_mutable_const/others.stderr

+14-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: a `const` item with interior mutability should not be borrowed
2-
--> tests/ui/borrow_interior_mutable_const/others.rs:54:5
2+
--> tests/ui/borrow_interior_mutable_const/others.rs:65:5
33
|
44
LL | ATOMIC.store(1, Ordering::SeqCst);
55
| ^^^^^^
@@ -12,103 +12,103 @@ LL | #![deny(clippy::borrow_interior_mutable_const)]
1212
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1313

1414
error: a `const` item with interior mutability should not be borrowed
15-
--> tests/ui/borrow_interior_mutable_const/others.rs:55:16
15+
--> tests/ui/borrow_interior_mutable_const/others.rs:66:16
1616
|
1717
LL | assert_eq!(ATOMIC.load(Ordering::SeqCst), 5);
1818
| ^^^^^^
1919
|
2020
= help: assign this const to a local or static variable, and use the variable here
2121

2222
error: a `const` item with interior mutability should not be borrowed
23-
--> tests/ui/borrow_interior_mutable_const/others.rs:58:22
23+
--> tests/ui/borrow_interior_mutable_const/others.rs:69:22
2424
|
2525
LL | let _once_ref = &ONCE_INIT;
2626
| ^^^^^^^^^
2727
|
2828
= help: assign this const to a local or static variable, and use the variable here
2929

3030
error: a `const` item with interior mutability should not be borrowed
31-
--> tests/ui/borrow_interior_mutable_const/others.rs:59:25
31+
--> tests/ui/borrow_interior_mutable_const/others.rs:70:25
3232
|
3333
LL | let _once_ref_2 = &&ONCE_INIT;
3434
| ^^^^^^^^^
3535
|
3636
= help: assign this const to a local or static variable, and use the variable here
3737

3838
error: a `const` item with interior mutability should not be borrowed
39-
--> tests/ui/borrow_interior_mutable_const/others.rs:60:27
39+
--> tests/ui/borrow_interior_mutable_const/others.rs:71:27
4040
|
4141
LL | let _once_ref_4 = &&&&ONCE_INIT;
4242
| ^^^^^^^^^
4343
|
4444
= help: assign this const to a local or static variable, and use the variable here
4545

4646
error: a `const` item with interior mutability should not be borrowed
47-
--> tests/ui/borrow_interior_mutable_const/others.rs:61:26
47+
--> tests/ui/borrow_interior_mutable_const/others.rs:72:26
4848
|
4949
LL | let _once_mut = &mut ONCE_INIT;
5050
| ^^^^^^^^^
5151
|
5252
= help: assign this const to a local or static variable, and use the variable here
5353

5454
error: a `const` item with interior mutability should not be borrowed
55-
--> tests/ui/borrow_interior_mutable_const/others.rs:72:14
55+
--> tests/ui/borrow_interior_mutable_const/others.rs:83:14
5656
|
5757
LL | let _ = &ATOMIC_TUPLE;
5858
| ^^^^^^^^^^^^
5959
|
6060
= help: assign this const to a local or static variable, and use the variable here
6161

6262
error: a `const` item with interior mutability should not be borrowed
63-
--> tests/ui/borrow_interior_mutable_const/others.rs:73:14
63+
--> tests/ui/borrow_interior_mutable_const/others.rs:84:14
6464
|
6565
LL | let _ = &ATOMIC_TUPLE.0;
6666
| ^^^^^^^^^^^^
6767
|
6868
= help: assign this const to a local or static variable, and use the variable here
6969

7070
error: a `const` item with interior mutability should not be borrowed
71-
--> tests/ui/borrow_interior_mutable_const/others.rs:74:19
71+
--> tests/ui/borrow_interior_mutable_const/others.rs:85:19
7272
|
7373
LL | let _ = &(&&&&ATOMIC_TUPLE).0;
7474
| ^^^^^^^^^^^^
7575
|
7676
= help: assign this const to a local or static variable, and use the variable here
7777

7878
error: a `const` item with interior mutability should not be borrowed
79-
--> tests/ui/borrow_interior_mutable_const/others.rs:75:14
79+
--> tests/ui/borrow_interior_mutable_const/others.rs:86:14
8080
|
8181
LL | let _ = &ATOMIC_TUPLE.0[0];
8282
| ^^^^^^^^^^^^
8383
|
8484
= help: assign this const to a local or static variable, and use the variable here
8585

8686
error: a `const` item with interior mutability should not be borrowed
87-
--> tests/ui/borrow_interior_mutable_const/others.rs:76:13
87+
--> tests/ui/borrow_interior_mutable_const/others.rs:87:13
8888
|
8989
LL | let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst);
9090
| ^^^^^^^^^^^^
9191
|
9292
= help: assign this const to a local or static variable, and use the variable here
9393

9494
error: a `const` item with interior mutability should not be borrowed
95-
--> tests/ui/borrow_interior_mutable_const/others.rs:81:13
95+
--> tests/ui/borrow_interior_mutable_const/others.rs:92:13
9696
|
9797
LL | let _ = ATOMIC_TUPLE.0[0];
9898
| ^^^^^^^^^^^^
9999
|
100100
= help: assign this const to a local or static variable, and use the variable here
101101

102102
error: a `const` item with interior mutability should not be borrowed
103-
--> tests/ui/borrow_interior_mutable_const/others.rs:86:5
103+
--> tests/ui/borrow_interior_mutable_const/others.rs:97:5
104104
|
105105
LL | CELL.set(2);
106106
| ^^^^
107107
|
108108
= help: assign this const to a local or static variable, and use the variable here
109109

110110
error: a `const` item with interior mutability should not be borrowed
111-
--> tests/ui/borrow_interior_mutable_const/others.rs:87:16
111+
--> tests/ui/borrow_interior_mutable_const/others.rs:98:16
112112
|
113113
LL | assert_eq!(CELL.get(), 6);
114114
| ^^^^

0 commit comments

Comments
 (0)