Skip to content

Commit 0abbccb

Browse files
committed
Rewrite tests for declare_interior_mutable_const and
`borrow_interior_mutable_const` to be more thorough on weird constructs
1 parent e809fd4 commit 0abbccb

19 files changed

+863
-1364
lines changed
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
//@aux-build:interior_mutable_const.rs
2+
3+
#![deny(clippy::borrow_interior_mutable_const)]
4+
#![allow(
5+
clippy::declare_interior_mutable_const,
6+
clippy::out_of_bounds_indexing,
7+
const_item_mutation,
8+
unconditional_panic
9+
)]
10+
11+
use core::cell::{Cell, UnsafeCell};
12+
use core::ops::{Deref, Index};
13+
14+
trait ConstDefault {
15+
const DEFAULT: Self;
16+
}
17+
impl ConstDefault for u32 {
18+
const DEFAULT: Self = 0;
19+
}
20+
impl<T: ConstDefault> ConstDefault for Cell<T> {
21+
const DEFAULT: Self = Cell::new(T::DEFAULT);
22+
}
23+
24+
fn main() {
25+
{
26+
const C: String = String::new();
27+
let _ = C;
28+
let _ = &C;
29+
let _ = C.len();
30+
let _ = &*C;
31+
}
32+
{
33+
const C: UnsafeCell<u32> = UnsafeCell::new(0);
34+
let _ = C;
35+
let _ = &C; //~ borrow_interior_mutable_const
36+
let _ = C.into_inner();
37+
let _ = C.get(); //~ borrow_interior_mutable_const
38+
}
39+
{
40+
const C: Cell<u32> = Cell::new(0);
41+
let _ = C;
42+
let _ = &C; //~ borrow_interior_mutable_const
43+
let _ = &mut C; //~ borrow_interior_mutable_const
44+
let _ = C.into_inner();
45+
46+
let local = C;
47+
C.swap(&local) //~ borrow_interior_mutable_const
48+
}
49+
{
50+
const C: [(Cell<u32>,); 1] = [(Cell::new(0),)];
51+
let _ = C;
52+
let _ = &C; //~ borrow_interior_mutable_const
53+
let _ = &C[0]; //~ borrow_interior_mutable_const
54+
let _ = &C[0].0; //~ borrow_interior_mutable_const
55+
C[0].0.set(1); //~ borrow_interior_mutable_const
56+
}
57+
{
58+
struct S(Cell<u32>);
59+
impl S {
60+
const C: Self = Self(Cell::new(0));
61+
}
62+
impl Deref for S {
63+
type Target = Cell<u32>;
64+
fn deref(&self) -> &Self::Target {
65+
&self.0
66+
}
67+
}
68+
let _ = S::C;
69+
let _ = S::C.0;
70+
let _ = &S::C; //~ borrow_interior_mutable_const
71+
let _ = &S::C.0; //~ borrow_interior_mutable_const
72+
S::C.set(1); //~ borrow_interior_mutable_const
73+
let _ = &*S::C; //~ borrow_interior_mutable_const
74+
(*S::C).set(1); //~ borrow_interior_mutable_const
75+
}
76+
{
77+
enum E {
78+
Cell(Cell<u32>),
79+
Other,
80+
}
81+
const CELL: E = E::Cell(Cell::new(0));
82+
const OTHER: E = E::Other;
83+
84+
let _ = CELL;
85+
let _ = &CELL; //~ borrow_interior_mutable_const
86+
let E::Cell(_) = CELL else {
87+
return;
88+
};
89+
90+
let _ = OTHER;
91+
let _ = &OTHER;
92+
let E::Cell(ref _x) = OTHER else {
93+
return;
94+
};
95+
}
96+
{
97+
struct S<T> {
98+
cell: (Cell<T>, u32),
99+
other: Option<T>,
100+
}
101+
impl<T: ConstDefault + Copy> S<T> {
102+
const C: Self = Self {
103+
cell: (Cell::<T>::DEFAULT, 0),
104+
other: Some(T::DEFAULT),
105+
};
106+
107+
fn f() {
108+
let _ = Self::C;
109+
let _ = &Self::C; //~ borrow_interior_mutable_const
110+
let _ = Self::C.other;
111+
let _ = &Self::C.other;
112+
let _ = &Self::C.cell; //~ borrow_interior_mutable_const
113+
let _ = &Self::C.cell.0; //~ borrow_interior_mutable_const
114+
Self::C.cell.0.set(T::DEFAULT); //~ borrow_interior_mutable_const
115+
let _ = &Self::C.cell.1;
116+
}
117+
}
118+
}
119+
{
120+
trait T {
121+
const VALUE: Option<Cell<u32>> = Some(Cell::new(0));
122+
}
123+
impl T for u32 {}
124+
impl T for i32 {
125+
const VALUE: Option<Cell<u32>> = None;
126+
}
127+
128+
let _ = &u32::VALUE; //~ borrow_interior_mutable_const
129+
let _ = &i32::VALUE;
130+
}
131+
{
132+
trait Trait<T: ConstDefault> {
133+
type T<U: ConstDefault>: ConstDefault;
134+
const VALUE: Option<Self::T<T>> = Some(Self::T::<T>::DEFAULT);
135+
}
136+
impl<T: ConstDefault> Trait<T> for u32 {
137+
type T<U: ConstDefault> = Cell<U>;
138+
}
139+
impl<T: ConstDefault> Trait<T> for i32 {
140+
type T<U: ConstDefault> = Cell<U>;
141+
const VALUE: Option<Cell<T>> = None;
142+
}
143+
144+
fn f<T: ConstDefault>() {
145+
let _ = &<u32 as Trait<T>>::VALUE; //~ borrow_interior_mutable_const
146+
let _ = &<i32 as Trait<T>>::VALUE;
147+
}
148+
}
149+
{
150+
trait Trait {
151+
const UNFROZEN: Option<Cell<u32>> = Some(Cell::new(0));
152+
const FROZEN: Option<Cell<u32>> = None;
153+
const NON_FREEZE: u32 = 0;
154+
}
155+
fn f<T: Trait>() {
156+
// None of these are guaranteed to be frozen, so don't lint.
157+
let _ = &T::UNFROZEN;
158+
let _ = &T::FROZEN;
159+
let _ = &T::NON_FREEZE;
160+
}
161+
}
162+
{
163+
struct S([Option<Cell<u32>>; 2]);
164+
impl Index<usize> for S {
165+
type Output = Option<Cell<u32>>;
166+
fn index(&self, idx: usize) -> &Self::Output {
167+
&self.0[idx]
168+
}
169+
}
170+
171+
const C: S = S([Some(Cell::new(0)), None]);
172+
let _ = &C; //~ borrow_interior_mutable_const
173+
let _ = &C[0]; //~ borrow_interior_mutable_const
174+
let _ = &C.0[0]; //~ borrow_interior_mutable_const
175+
let _ = &C.0[1];
176+
}
177+
{
178+
const C: [Option<Cell<u32>>; 2] = [None, None];
179+
let _ = &C[0];
180+
let _ = &C[1];
181+
let _ = &C[2];
182+
183+
fn f(i: usize) {
184+
let _ = &C[i];
185+
}
186+
}
187+
{
188+
const C: [Option<Cell<u32>>; 2] = [None, Some(Cell::new(0))];
189+
let _ = &C[0];
190+
let _ = &C[1]; //~ borrow_interior_mutable_const
191+
let _ = &C[2];
192+
193+
fn f(i: usize) {
194+
let _ = &C[i]; //~ borrow_interior_mutable_const
195+
}
196+
}
197+
{
198+
let _ = &interior_mutable_const::WRAPPED_PRIVATE_UNFROZEN_VARIANT; //~ borrow_interior_mutable_const
199+
let _ = &interior_mutable_const::WRAPPED_PRIVATE_FROZEN_VARIANT;
200+
}
201+
{
202+
type Cell2<T> = Cell<T>;
203+
type MyCell = Cell2<u32>;
204+
struct S(Option<MyCell>);
205+
trait T {
206+
type Assoc;
207+
}
208+
struct S2<T>(T, T, u32);
209+
impl T for S {
210+
type Assoc = S2<Self>;
211+
}
212+
type Assoc<X> = <X as T>::Assoc;
213+
impl S {
214+
const VALUE: Assoc<Self> = S2(Self(None), Self(Some(Cell::new(0))), 0);
215+
}
216+
let _ = &S::VALUE; //~ borrow_interior_mutable_const
217+
let _ = &S::VALUE.0;
218+
let _ = &S::VALUE.1; //~ borrow_interior_mutable_const
219+
let _ = &S::VALUE.2;
220+
}
221+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy