From 662df33e976e2143f1ca839425b995f0eebf9c6e Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Sun, 13 Feb 2022 13:22:17 -0500 Subject: [PATCH] Fix `transmute_undefined_repr` with single field `#[repr(C)]` structs --- clippy_lints/src/lib.register_all.rs | 1 + clippy_lints/src/lib.register_correctness.rs | 1 + clippy_lints/src/lib.register_nursery.rs | 1 - clippy_lints/src/transmute/mod.rs | 5 +++-- clippy_lints/src/transmute/transmute_undefined_repr.rs | 9 +++++---- tests/ui/transmute_undefined_repr.rs | 4 ++++ 6 files changed, 14 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/lib.register_all.rs b/clippy_lints/src/lib.register_all.rs index 4721b7f2b472..d93e34e76b49 100644 --- a/clippy_lints/src/lib.register_all.rs +++ b/clippy_lints/src/lib.register_all.rs @@ -277,6 +277,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![ LintId::of(transmute::TRANSMUTE_INT_TO_FLOAT), LintId::of(transmute::TRANSMUTE_NUM_TO_BYTES), LintId::of(transmute::TRANSMUTE_PTR_TO_REF), + LintId::of(transmute::TRANSMUTE_UNDEFINED_REPR), LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE), LintId::of(transmute::WRONG_TRANSMUTE), LintId::of(transmuting_null::TRANSMUTING_NULL), diff --git a/clippy_lints/src/lib.register_correctness.rs b/clippy_lints/src/lib.register_correctness.rs index 4217fd3a3ea7..d013daa8e082 100644 --- a/clippy_lints/src/lib.register_correctness.rs +++ b/clippy_lints/src/lib.register_correctness.rs @@ -58,6 +58,7 @@ store.register_group(true, "clippy::correctness", Some("clippy_correctness"), ve LintId::of(size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT), LintId::of(swap::ALMOST_SWAPPED), LintId::of(to_string_in_display::TO_STRING_IN_DISPLAY), + LintId::of(transmute::TRANSMUTE_UNDEFINED_REPR), LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE), LintId::of(transmute::WRONG_TRANSMUTE), LintId::of(transmuting_null::TRANSMUTING_NULL), diff --git a/clippy_lints/src/lib.register_nursery.rs b/clippy_lints/src/lib.register_nursery.rs index 8d4dde42bbec..a73537901002 100644 --- a/clippy_lints/src/lib.register_nursery.rs +++ b/clippy_lints/src/lib.register_nursery.rs @@ -26,7 +26,6 @@ store.register_group(true, "clippy::nursery", Some("clippy_nursery"), vec![ LintId::of(strings::STRING_LIT_AS_BYTES), LintId::of(suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS), LintId::of(trailing_empty_array::TRAILING_EMPTY_ARRAY), - LintId::of(transmute::TRANSMUTE_UNDEFINED_REPR), LintId::of(transmute::USELESS_TRANSMUTE), LintId::of(use_self::USE_SELF), ]) diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index 5e94ab6d0482..22a8c53a5852 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -358,7 +358,8 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for transmutes either to or from a type which does not have a defined representation. + /// Checks for transmutes between types which do not have a representation defined relative to + /// each other. /// /// ### Why is this bad? /// The results of such a transmute are not defined. @@ -376,7 +377,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.60.0"] pub TRANSMUTE_UNDEFINED_REPR, - nursery, + correctness, "transmute to or from a type with an undefined representation" } diff --git a/clippy_lints/src/transmute/transmute_undefined_repr.rs b/clippy_lints/src/transmute/transmute_undefined_repr.rs index c91bc3245e41..89439862f691 100644 --- a/clippy_lints/src/transmute/transmute_undefined_repr.rs +++ b/clippy_lints/src/transmute/transmute_undefined_repr.rs @@ -255,9 +255,6 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx> ReducedTy::UnorderedFields(ty) }, ty::Adt(def, substs) if def.is_struct() => { - if def.repr.inhibit_struct_field_reordering_opt() { - return ReducedTy::OrderedFields(ty); - } let mut iter = def .non_enum_variant() .fields @@ -270,7 +267,11 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx> ty = sized_ty; continue; } - ReducedTy::UnorderedFields(ty) + if def.repr.inhibit_struct_field_reordering_opt() { + ReducedTy::OrderedFields(ty) + } else { + ReducedTy::UnorderedFields(ty) + } }, ty::Ref(..) | ty::RawPtr(_) => ReducedTy::Ref(ty), _ => ReducedTy::Other(ty), diff --git a/tests/ui/transmute_undefined_repr.rs b/tests/ui/transmute_undefined_repr.rs index 71539940fbf2..f0383a03fbde 100644 --- a/tests/ui/transmute_undefined_repr.rs +++ b/tests/ui/transmute_undefined_repr.rs @@ -40,5 +40,9 @@ fn main() { let _: Ty<[u8; 8]> = core::mem::transmute(value::>()); // Ok, transmute to byte array let _: Ty2 = core::mem::transmute(value::>()); // Ok, transmute from byte array + + // issue #8417 + let _: Ty2C, ()> = core::mem::transmute(value::>()); // Ok, Ty2 types are the same + let _: Ty2 = core::mem::transmute(value::, ()>>()); // Ok, Ty2 types are the same } }