Skip to content

Commit 0f2daf3

Browse files
committed
limit local ADT types to size_of
1 parent e998bb8 commit 0f2daf3

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

clippy_lints/src/casts/cast_possible_truncation.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b
100100
&& let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id()
101101
&& cx.tcx.is_diagnostic_item(sym::mem_size_of, def_id)
102102
&& let Some(ty) = cx.typeck_results().node_args(func.hir_id).types().next()
103+
&& is_valid_sizeof(ty)
103104
&& let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(ty))
104105
{
105106
let size: u64 = layout.layout.size().bytes();
@@ -228,3 +229,17 @@ fn offer_suggestion(
228229
SuggestionStyle::ShowAlways,
229230
);
230231
}
232+
233+
// FIXME(@tesuji): May extend this to a validator functions to include:
234+
// * some ABI-guaranteed STD types,
235+
// * some non-local crate types suggested in [PR-12962][1].
236+
// [1]: https://github.com/rust-lang/rust-clippy/pull/12962#discussion_r1661500351
237+
fn is_valid_sizeof<'tcx>(ty: Ty<'tcx>) -> bool {
238+
if ty.is_primitive_ty() || ty.is_any_ptr() || ty.is_box() || ty.is_slice() {
239+
return true;
240+
}
241+
match ty.kind() {
242+
ty::Adt(def, ..) if def.did().is_local() => true,
243+
_ => false,
244+
}
245+
}

tests/ui/cast.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,5 +511,8 @@ pub fn issue_9613() {
511511
CHUNK as u32;
512512
u64::MIN as u32;
513513
//~^ ERROR: casting `u64` to `u32` may truncate the value
514+
struct Foo(usize, u32);
515+
core::mem::size_of::<Foo>() as u32;
514516
core::mem::size_of::<String>() as u32;
517+
//~^ ERROR: casting `usize` to `u32` may truncate
515518
}

tests/ui/cast.stderr

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ LL | u8::try_from(255 % 999999u64);
732732
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
733733

734734
error: casting `u64` to `u32` may truncate the value
735-
--> tests/ui/cast.rs:510:5
735+
--> tests/ui/cast.rs:512:5
736736
|
737737
LL | u64::MIN as u32;
738738
| ^^^^^^^^^^^^^^^
@@ -743,5 +743,17 @@ help: ... or use `try_from` and handle the error accordingly
743743
LL | u32::try_from(u64::MIN);
744744
| ~~~~~~~~~~~~~~~~~~~~~~~
745745

746-
error: aborting due to 93 previous errors
746+
error: casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers
747+
--> tests/ui/cast.rs:516:5
748+
|
749+
LL | core::mem::size_of::<String>() as u32;
750+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
751+
|
752+
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
753+
help: ... or use `try_from` and handle the error accordingly
754+
|
755+
LL | u32::try_from(core::mem::size_of::<String>());
756+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
757+
758+
error: aborting due to 94 previous errors
747759

0 commit comments

Comments
 (0)