summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs')
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs164
1 files changed, 66 insertions, 98 deletions
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
index 3d4bbbf64..34642f4b1 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
@@ -27,32 +27,24 @@ pub(super) fn check<'tcx>(
// `Repr(C)` <-> unordered type.
// If the first field of the `Repr(C)` type matches then the transmute is ok
- (
- ReducedTy::OrderedFields(_, Some(from_sub_ty)),
- ReducedTy::UnorderedFields(to_sub_ty),
- )
- | (
- ReducedTy::UnorderedFields(from_sub_ty),
- ReducedTy::OrderedFields(_, Some(to_sub_ty)),
- ) => {
+ (ReducedTy::OrderedFields(_, Some(from_sub_ty)), ReducedTy::UnorderedFields(to_sub_ty))
+ | (ReducedTy::UnorderedFields(from_sub_ty), ReducedTy::OrderedFields(_, Some(to_sub_ty))) => {
from_ty = from_sub_ty;
to_ty = to_sub_ty;
continue;
- }
- (ReducedTy::OrderedFields(_, Some(from_sub_ty)), ReducedTy::Other(to_sub_ty))
- if reduced_tys.to_fat_ptr =>
- {
+ },
+ (ReducedTy::OrderedFields(_, Some(from_sub_ty)), ReducedTy::Other(to_sub_ty)) if reduced_tys.to_fat_ptr => {
from_ty = from_sub_ty;
to_ty = to_sub_ty;
continue;
- }
+ },
(ReducedTy::Other(from_sub_ty), ReducedTy::OrderedFields(_, Some(to_sub_ty)))
if reduced_tys.from_fat_ptr =>
{
from_ty = from_sub_ty;
to_ty = to_sub_ty;
continue;
- }
+ },
// ptr <-> ptr
(ReducedTy::Other(from_sub_ty), ReducedTy::Other(to_sub_ty))
@@ -62,19 +54,19 @@ pub(super) fn check<'tcx>(
from_ty = from_sub_ty;
to_ty = to_sub_ty;
continue;
- }
+ },
// fat ptr <-> (*size, *size)
(ReducedTy::Other(_), ReducedTy::UnorderedFields(to_ty))
if reduced_tys.from_fat_ptr && is_size_pair(to_ty) =>
{
return false;
- }
+ },
(ReducedTy::UnorderedFields(from_ty), ReducedTy::Other(_))
if reduced_tys.to_fat_ptr && is_size_pair(from_ty) =>
{
return false;
- }
+ },
// fat ptr -> some struct | some struct -> fat ptr
(ReducedTy::Other(_), _) if reduced_tys.from_fat_ptr => {
@@ -85,14 +77,12 @@ pub(super) fn check<'tcx>(
&format!("transmute from `{from_ty_orig}` which has an undefined layout"),
|diag| {
if from_ty_orig.peel_refs() != from_ty.peel_refs() {
- diag.note(&format!(
- "the contained type `{from_ty}` has an undefined layout"
- ));
+ diag.note(&format!("the contained type `{from_ty}` has an undefined layout"));
}
},
);
return true;
- }
+ },
(_, ReducedTy::Other(_)) if reduced_tys.to_fat_ptr => {
span_lint_and_then(
cx,
@@ -101,18 +91,14 @@ pub(super) fn check<'tcx>(
&format!("transmute to `{to_ty_orig}` which has an undefined layout"),
|diag| {
if to_ty_orig.peel_refs() != to_ty.peel_refs() {
- diag.note(&format!(
- "the contained type `{to_ty}` has an undefined layout"
- ));
+ diag.note(&format!("the contained type `{to_ty}` has an undefined layout"));
}
},
);
return true;
- }
+ },
- (ReducedTy::UnorderedFields(from_ty), ReducedTy::UnorderedFields(to_ty))
- if from_ty != to_ty =>
- {
+ (ReducedTy::UnorderedFields(from_ty), ReducedTy::UnorderedFields(to_ty)) if from_ty != to_ty => {
let same_adt_did = if let (ty::Adt(from_def, from_subs), ty::Adt(to_def, to_subs))
= (from_ty.kind(), to_ty.kind())
&& from_def == to_def
@@ -139,25 +125,19 @@ pub(super) fn check<'tcx>(
));
} else {
if from_ty_orig.peel_refs() != from_ty {
- diag.note(&format!(
- "the contained type `{from_ty}` has an undefined layout"
- ));
+ diag.note(&format!("the contained type `{from_ty}` has an undefined layout"));
}
if to_ty_orig.peel_refs() != to_ty {
- diag.note(&format!(
- "the contained type `{to_ty}` has an undefined layout"
- ));
+ diag.note(&format!("the contained type `{to_ty}` has an undefined layout"));
}
}
},
);
return true;
- }
+ },
(
ReducedTy::UnorderedFields(from_ty),
- ReducedTy::Other(_)
- | ReducedTy::OrderedFields(..)
- | ReducedTy::TypeErasure { raw_ptr_only: true },
+ ReducedTy::Other(_) | ReducedTy::OrderedFields(..) | ReducedTy::TypeErasure { raw_ptr_only: true },
) => {
span_lint_and_then(
cx,
@@ -166,18 +146,14 @@ pub(super) fn check<'tcx>(
&format!("transmute from `{from_ty_orig}` which has an undefined layout"),
|diag| {
if from_ty_orig.peel_refs() != from_ty {
- diag.note(&format!(
- "the contained type `{from_ty}` has an undefined layout"
- ));
+ diag.note(&format!("the contained type `{from_ty}` has an undefined layout"));
}
},
);
return true;
- }
+ },
(
- ReducedTy::Other(_)
- | ReducedTy::OrderedFields(..)
- | ReducedTy::TypeErasure { raw_ptr_only: true },
+ ReducedTy::Other(_) | ReducedTy::OrderedFields(..) | ReducedTy::TypeErasure { raw_ptr_only: true },
ReducedTy::UnorderedFields(to_ty),
) => {
span_lint_and_then(
@@ -187,25 +163,19 @@ pub(super) fn check<'tcx>(
&format!("transmute into `{to_ty_orig}` which has an undefined layout"),
|diag| {
if to_ty_orig.peel_refs() != to_ty {
- diag.note(&format!(
- "the contained type `{to_ty}` has an undefined layout"
- ));
+ diag.note(&format!("the contained type `{to_ty}` has an undefined layout"));
}
},
);
return true;
- }
+ },
(
- ReducedTy::OrderedFields(..)
- | ReducedTy::Other(_)
- | ReducedTy::TypeErasure { raw_ptr_only: true },
- ReducedTy::OrderedFields(..)
- | ReducedTy::Other(_)
- | ReducedTy::TypeErasure { raw_ptr_only: true },
+ ReducedTy::OrderedFields(..) | ReducedTy::Other(_) | ReducedTy::TypeErasure { raw_ptr_only: true },
+ ReducedTy::OrderedFields(..) | ReducedTy::Other(_) | ReducedTy::TypeErasure { raw_ptr_only: true },
)
| (ReducedTy::UnorderedFields(_), ReducedTy::UnorderedFields(_)) => {
break;
- }
+ },
}
}
@@ -223,38 +193,42 @@ struct ReducedTys<'tcx> {
}
/// Remove references so long as both types are references.
-fn reduce_refs<'tcx>(
- cx: &LateContext<'tcx>,
- mut from_ty: Ty<'tcx>,
- mut to_ty: Ty<'tcx>,
-) -> ReducedTys<'tcx> {
+fn reduce_refs<'tcx>(cx: &LateContext<'tcx>, mut from_ty: Ty<'tcx>, mut to_ty: Ty<'tcx>) -> ReducedTys<'tcx> {
let mut from_raw_ptr = false;
let mut to_raw_ptr = false;
- let (from_fat_ptr, to_fat_ptr) =
- loop {
- break match (from_ty.kind(), to_ty.kind()) {
- (
- &(ty::Ref(_, from_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: from_sub_ty, .. })),
- &(ty::Ref(_, to_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: to_sub_ty, .. })),
- ) => {
- from_raw_ptr = matches!(*from_ty.kind(), ty::RawPtr(_));
- from_ty = from_sub_ty;
- to_raw_ptr = matches!(*to_ty.kind(), ty::RawPtr(_));
- to_ty = to_sub_ty;
- continue;
- }
- (
- &(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })),
- _,
- ) if !unsized_ty.is_sized(cx.tcx, cx.param_env) => (true, false),
- (
- _,
- &(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })),
- ) if !unsized_ty.is_sized(cx.tcx, cx.param_env) => (false, true),
- _ => (false, false),
- };
+ let (from_fat_ptr, to_fat_ptr) = loop {
+ break match (from_ty.kind(), to_ty.kind()) {
+ (
+ &(ty::Ref(_, from_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: from_sub_ty, .. })),
+ &(ty::Ref(_, to_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: to_sub_ty, .. })),
+ ) => {
+ from_raw_ptr = matches!(*from_ty.kind(), ty::RawPtr(_));
+ from_ty = from_sub_ty;
+ to_raw_ptr = matches!(*to_ty.kind(), ty::RawPtr(_));
+ to_ty = to_sub_ty;
+ continue;
+ },
+ (&(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })), _)
+ if !unsized_ty.is_sized(cx.tcx, cx.param_env) =>
+ {
+ (true, false)
+ },
+ (_, &(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })))
+ if !unsized_ty.is_sized(cx.tcx, cx.param_env) =>
+ {
+ (false, true)
+ },
+ _ => (false, false),
};
- ReducedTys { from_ty, to_ty, from_raw_ptr, to_raw_ptr, from_fat_ptr, to_fat_ptr }
+ };
+ ReducedTys {
+ from_ty,
+ to_ty,
+ from_raw_ptr,
+ to_raw_ptr,
+ from_fat_ptr,
+ to_fat_ptr,
+ }
}
enum ReducedTy<'tcx> {
@@ -277,11 +251,11 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
return match *ty.kind() {
ty::Array(sub_ty, _) if matches!(sub_ty.kind(), ty::Int(_) | ty::Uint(_)) => {
ReducedTy::TypeErasure { raw_ptr_only: false }
- }
+ },
ty::Array(sub_ty, _) | ty::Slice(sub_ty) => {
ty = sub_ty;
continue;
- }
+ },
ty::Tuple(args) if args.is_empty() => ReducedTy::TypeErasure { raw_ptr_only: false },
ty::Tuple(args) => {
let mut iter = args.iter();
@@ -293,7 +267,7 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
continue;
}
ReducedTy::UnorderedFields(ty)
- }
+ },
ty::Adt(def, substs) if def.is_struct() => {
let mut iter = def
.non_enum_variant()
@@ -312,12 +286,10 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
} else {
ReducedTy::UnorderedFields(ty)
}
- }
- ty::Adt(def, _)
- if def.is_enum() && (def.variants().is_empty() || is_c_void(cx, ty)) =>
- {
+ },
+ ty::Adt(def, _) if def.is_enum() && (def.variants().is_empty() || is_c_void(cx, ty)) => {
ReducedTy::TypeErasure { raw_ptr_only: false }
- }
+ },
// TODO: Check if the conversion to or from at least one of a union's fields is valid.
ty::Adt(def, _) if def.is_union() => ReducedTy::TypeErasure { raw_ptr_only: false },
ty::Foreign(_) | ty::Param(_) => ReducedTy::TypeErasure { raw_ptr_only: false },
@@ -356,11 +328,7 @@ fn same_except_params<'tcx>(subs1: SubstsRef<'tcx>, subs2: SubstsRef<'tcx>) -> b
for (ty1, ty2) in subs1.types().zip(subs2.types()).filter(|(ty1, ty2)| ty1 != ty2) {
match (ty1.kind(), ty2.kind()) {
(ty::Param(_), _) | (_, ty::Param(_)) => (),
- (ty::Adt(adt1, subs1), ty::Adt(adt2, subs2))
- if adt1 == adt2 && same_except_params(subs1, subs2) =>
- {
- ()
- }
+ (ty::Adt(adt1, subs1), ty::Adt(adt2, subs2)) if adt1 == adt2 && same_except_params(subs1, subs2) => (),
_ => return false,
}
}