Skip to content

Commit 886d5fb

Browse files
committed
Auto merge of rust-lang#11508 - Jarcho:issue_11474, r=blyxyas
Lint `needless_borrow` and `explicit_auto_deref` on most union field accesses Changes both lints to follow rustc's rules around auto-deref through `ManuallyDrop` union fields rather than just bailing on union fields. changelog: [`needless_borrow`] & [`explicit_auto_deref`]: Lint on most union field accesses
2 parents 8ee9a9c + 1a01132 commit 886d5fb

File tree

8 files changed

+352
-150
lines changed

8 files changed

+352
-150
lines changed

clippy_lints/src/dereference.rs

Lines changed: 151 additions & 96 deletions
Large diffs are not rendered by default.

clippy_utils/src/ty.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,3 +1266,8 @@ pub fn normalize_with_regions<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>
12661266
Err(_) => ty,
12671267
}
12681268
}
1269+
1270+
/// Checks if the type is `core::mem::ManuallyDrop<_>`
1271+
pub fn is_manually_drop(ty: Ty<'_>) -> bool {
1272+
ty.ty_adt_def().map_or(false, AdtDef::is_manually_drop)
1273+
}

tests/ui/explicit_auto_deref.fixed

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -301,24 +301,47 @@ fn main() {
301301
};
302302

303303
// Issue #11474
304-
pub struct Variant {
305-
pub anonymous: Variant0,
304+
#[derive(Clone, Copy)]
305+
struct Wrap<T>(T);
306+
impl<T> core::ops::Deref for Wrap<T> {
307+
type Target = T;
308+
fn deref(&self) -> &T {
309+
&self.0
310+
}
306311
}
307-
308-
pub union Variant0 {
309-
pub anonymous: std::mem::ManuallyDrop<Variant00>,
312+
impl<T> core::ops::DerefMut for Wrap<T> {
313+
fn deref_mut(&mut self) -> &mut T {
314+
&mut self.0
315+
}
310316
}
311317

312-
pub struct Variant00 {
313-
pub anonymous: Variant000,
318+
union U<T: Copy> {
319+
u: T,
314320
}
315321

316-
pub union Variant000 {
317-
pub val: i32,
322+
#[derive(Clone, Copy)]
323+
struct S8 {
324+
x: &'static str,
318325
}
319326

320327
unsafe {
321-
let mut p = core::mem::zeroed::<Variant>();
322-
(*p.anonymous.anonymous).anonymous.val = 1;
328+
let mut x = U {
329+
u: core::mem::ManuallyDrop::new(S8 { x: "" }),
330+
};
331+
let _ = &mut (*x.u).x;
332+
let _ = &mut { x.u }.x;
333+
let _ = &mut ({ *x.u }).x;
334+
335+
let mut x = U {
336+
u: Wrap(core::mem::ManuallyDrop::new(S8 { x: "" })),
337+
};
338+
let _ = &mut (*x.u).x;
339+
let _ = &mut { x.u }.x;
340+
let _ = &mut ({ **x.u }).x;
341+
342+
let mut x = U { u: Wrap(S8 { x: "" }) };
343+
let _ = &mut x.u.x;
344+
let _ = &mut { x.u }.x;
345+
let _ = &mut ({ *x.u }).x;
323346
}
324347
}

tests/ui/explicit_auto_deref.rs

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -301,24 +301,47 @@ fn main() {
301301
};
302302

303303
// Issue #11474
304-
pub struct Variant {
305-
pub anonymous: Variant0,
304+
#[derive(Clone, Copy)]
305+
struct Wrap<T>(T);
306+
impl<T> core::ops::Deref for Wrap<T> {
307+
type Target = T;
308+
fn deref(&self) -> &T {
309+
&self.0
310+
}
306311
}
307-
308-
pub union Variant0 {
309-
pub anonymous: std::mem::ManuallyDrop<Variant00>,
312+
impl<T> core::ops::DerefMut for Wrap<T> {
313+
fn deref_mut(&mut self) -> &mut T {
314+
&mut self.0
315+
}
310316
}
311317

312-
pub struct Variant00 {
313-
pub anonymous: Variant000,
318+
union U<T: Copy> {
319+
u: T,
314320
}
315321

316-
pub union Variant000 {
317-
pub val: i32,
322+
#[derive(Clone, Copy)]
323+
struct S8 {
324+
x: &'static str,
318325
}
319326

320327
unsafe {
321-
let mut p = core::mem::zeroed::<Variant>();
322-
(*p.anonymous.anonymous).anonymous.val = 1;
328+
let mut x = U {
329+
u: core::mem::ManuallyDrop::new(S8 { x: "" }),
330+
};
331+
let _ = &mut (*x.u).x;
332+
let _ = &mut (*{ x.u }).x;
333+
let _ = &mut ({ *x.u }).x;
334+
335+
let mut x = U {
336+
u: Wrap(core::mem::ManuallyDrop::new(S8 { x: "" })),
337+
};
338+
let _ = &mut (**x.u).x;
339+
let _ = &mut (**{ x.u }).x;
340+
let _ = &mut ({ **x.u }).x;
341+
342+
let mut x = U { u: Wrap(S8 { x: "" }) };
343+
let _ = &mut (*x.u).x;
344+
let _ = &mut (*{ x.u }).x;
345+
let _ = &mut ({ *x.u }).x;
323346
}
324347
}

tests/ui/explicit_auto_deref.stderr

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,5 +241,35 @@ error: deref which would be done by auto-deref
241241
LL | Some(x) => &mut *x,
242242
| ^^^^^^^ help: try: `x`
243243

244-
error: aborting due to 40 previous errors
244+
error: deref which would be done by auto-deref
245+
--> $DIR/explicit_auto_deref.rs:332:22
246+
|
247+
LL | let _ = &mut (*{ x.u }).x;
248+
| ^^^^^^^^^^ help: try: `{ x.u }`
249+
250+
error: deref which would be done by auto-deref
251+
--> $DIR/explicit_auto_deref.rs:338:22
252+
|
253+
LL | let _ = &mut (**x.u).x;
254+
| ^^^^^^^ help: try: `(*x.u)`
255+
256+
error: deref which would be done by auto-deref
257+
--> $DIR/explicit_auto_deref.rs:339:22
258+
|
259+
LL | let _ = &mut (**{ x.u }).x;
260+
| ^^^^^^^^^^^ help: try: `{ x.u }`
261+
262+
error: deref which would be done by auto-deref
263+
--> $DIR/explicit_auto_deref.rs:343:22
264+
|
265+
LL | let _ = &mut (*x.u).x;
266+
| ^^^^^^ help: try: `x.u`
267+
268+
error: deref which would be done by auto-deref
269+
--> $DIR/explicit_auto_deref.rs:344:22
270+
|
271+
LL | let _ = &mut (*{ x.u }).x;
272+
| ^^^^^^^^^^ help: try: `{ x.u }`
273+
274+
error: aborting due to 45 previous errors
245275

tests/ui/needless_borrow.fixed

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -190,27 +190,48 @@ fn issue9383() {
190190
// Should not lint because unions need explicit deref when accessing field
191191
use std::mem::ManuallyDrop;
192192

193-
union Coral {
194-
crab: ManuallyDrop<Vec<i32>>,
193+
#[derive(Clone, Copy)]
194+
struct Wrap<T>(T);
195+
impl<T> core::ops::Deref for Wrap<T> {
196+
type Target = T;
197+
fn deref(&self) -> &T {
198+
&self.0
199+
}
200+
}
201+
impl<T> core::ops::DerefMut for Wrap<T> {
202+
fn deref_mut(&mut self) -> &mut T {
203+
&mut self.0
204+
}
195205
}
196206

197-
union Ocean {
198-
coral: ManuallyDrop<Coral>,
207+
union U<T: Copy> {
208+
u: T,
199209
}
200210

201-
let mut ocean = Ocean {
202-
coral: ManuallyDrop::new(Coral {
203-
crab: ManuallyDrop::new(vec![1, 2, 3]),
204-
}),
205-
};
211+
#[derive(Clone, Copy)]
212+
struct Foo {
213+
x: u32,
214+
}
206215

207216
unsafe {
208-
ManuallyDrop::drop(&mut (&mut ocean.coral).crab);
209-
210-
(*ocean.coral).crab = ManuallyDrop::new(vec![4, 5, 6]);
211-
ManuallyDrop::drop(&mut (*ocean.coral).crab);
212-
213-
ManuallyDrop::drop(&mut ocean.coral);
217+
let mut x = U {
218+
u: ManuallyDrop::new(Foo { x: 0 }),
219+
};
220+
let _ = &mut (&mut x.u).x;
221+
let _ = &mut { x.u }.x;
222+
let _ = &mut ({ &mut x.u }).x;
223+
224+
let mut x = U {
225+
u: Wrap(ManuallyDrop::new(Foo { x: 0 })),
226+
};
227+
let _ = &mut (&mut x.u).x;
228+
let _ = &mut { x.u }.x;
229+
let _ = &mut ({ &mut x.u }).x;
230+
231+
let mut x = U { u: Wrap(Foo { x: 0 }) };
232+
let _ = &mut x.u.x;
233+
let _ = &mut { x.u }.x;
234+
let _ = &mut ({ &mut x.u }).x;
214235
}
215236
}
216237

tests/ui/needless_borrow.rs

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -190,27 +190,48 @@ fn issue9383() {
190190
// Should not lint because unions need explicit deref when accessing field
191191
use std::mem::ManuallyDrop;
192192

193-
union Coral {
194-
crab: ManuallyDrop<Vec<i32>>,
193+
#[derive(Clone, Copy)]
194+
struct Wrap<T>(T);
195+
impl<T> core::ops::Deref for Wrap<T> {
196+
type Target = T;
197+
fn deref(&self) -> &T {
198+
&self.0
199+
}
200+
}
201+
impl<T> core::ops::DerefMut for Wrap<T> {
202+
fn deref_mut(&mut self) -> &mut T {
203+
&mut self.0
204+
}
195205
}
196206

197-
union Ocean {
198-
coral: ManuallyDrop<Coral>,
207+
union U<T: Copy> {
208+
u: T,
199209
}
200210

201-
let mut ocean = Ocean {
202-
coral: ManuallyDrop::new(Coral {
203-
crab: ManuallyDrop::new(vec![1, 2, 3]),
204-
}),
205-
};
211+
#[derive(Clone, Copy)]
212+
struct Foo {
213+
x: u32,
214+
}
206215

207216
unsafe {
208-
ManuallyDrop::drop(&mut (&mut ocean.coral).crab);
209-
210-
(*ocean.coral).crab = ManuallyDrop::new(vec![4, 5, 6]);
211-
ManuallyDrop::drop(&mut (*ocean.coral).crab);
212-
213-
ManuallyDrop::drop(&mut ocean.coral);
217+
let mut x = U {
218+
u: ManuallyDrop::new(Foo { x: 0 }),
219+
};
220+
let _ = &mut (&mut x.u).x;
221+
let _ = &mut (&mut { x.u }).x;
222+
let _ = &mut ({ &mut x.u }).x;
223+
224+
let mut x = U {
225+
u: Wrap(ManuallyDrop::new(Foo { x: 0 })),
226+
};
227+
let _ = &mut (&mut x.u).x;
228+
let _ = &mut (&mut { x.u }).x;
229+
let _ = &mut ({ &mut x.u }).x;
230+
231+
let mut x = U { u: Wrap(Foo { x: 0 }) };
232+
let _ = &mut (&mut x.u).x;
233+
let _ = &mut (&mut { x.u }).x;
234+
let _ = &mut ({ &mut x.u }).x;
214235
}
215236
}
216237

tests/ui/needless_borrow.stderr

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,5 +133,29 @@ error: this expression borrows a value the compiler would automatically borrow
133133
LL | (&mut self.f)()
134134
| ^^^^^^^^^^^^^ help: change this to: `(self.f)`
135135

136-
error: aborting due to 22 previous errors
136+
error: this expression borrows a value the compiler would automatically borrow
137+
--> $DIR/needless_borrow.rs:221:22
138+
|
139+
LL | let _ = &mut (&mut { x.u }).x;
140+
| ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`
141+
142+
error: this expression borrows a value the compiler would automatically borrow
143+
--> $DIR/needless_borrow.rs:228:22
144+
|
145+
LL | let _ = &mut (&mut { x.u }).x;
146+
| ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`
147+
148+
error: this expression borrows a value the compiler would automatically borrow
149+
--> $DIR/needless_borrow.rs:232:22
150+
|
151+
LL | let _ = &mut (&mut x.u).x;
152+
| ^^^^^^^^^^ help: change this to: `x.u`
153+
154+
error: this expression borrows a value the compiler would automatically borrow
155+
--> $DIR/needless_borrow.rs:233:22
156+
|
157+
LL | let _ = &mut (&mut { x.u }).x;
158+
| ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`
159+
160+
error: aborting due to 26 previous errors
137161

0 commit comments

Comments
 (0)