Don't lint transmute_undefined_repr
when the the first field of a repr(C)
type is compatible with the other type
This commit is contained in:
parent
71777465cc
commit
b426bd52a1
@ -164,9 +164,18 @@ pub(super) fn check<'tcx>(
|
||||
);
|
||||
return true;
|
||||
},
|
||||
// `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::Ref(from_sub_ty), ReducedTy::Ref(to_sub_ty)) => {
|
||||
from_ty = from_sub_ty;
|
||||
to_ty = to_sub_ty;
|
||||
continue;
|
||||
},
|
||||
(
|
||||
ReducedTy::UnorderedFields(from_ty),
|
||||
ReducedTy::Other(_) | ReducedTy::OrderedFields(_) | ReducedTy::Ref(_),
|
||||
ReducedTy::Other(_) | ReducedTy::OrderedFields(..) | ReducedTy::Ref(_),
|
||||
) => {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
@ -182,7 +191,7 @@ pub(super) fn check<'tcx>(
|
||||
return true;
|
||||
},
|
||||
(
|
||||
ReducedTy::Other(_) | ReducedTy::OrderedFields(_) | ReducedTy::Ref(_),
|
||||
ReducedTy::Other(_) | ReducedTy::OrderedFields(..) | ReducedTy::Ref(_),
|
||||
ReducedTy::UnorderedFields(to_ty),
|
||||
) => {
|
||||
span_lint_and_then(
|
||||
@ -198,14 +207,9 @@ pub(super) fn check<'tcx>(
|
||||
);
|
||||
return true;
|
||||
},
|
||||
(ReducedTy::Ref(from_sub_ty), ReducedTy::Ref(to_sub_ty)) => {
|
||||
from_ty = from_sub_ty;
|
||||
to_ty = to_sub_ty;
|
||||
continue;
|
||||
},
|
||||
(
|
||||
ReducedTy::OrderedFields(_) | ReducedTy::Ref(_) | ReducedTy::Other(_) | ReducedTy::Param,
|
||||
ReducedTy::OrderedFields(_) | ReducedTy::Ref(_) | ReducedTy::Other(_) | ReducedTy::Param,
|
||||
ReducedTy::OrderedFields(..) | ReducedTy::Ref(_) | ReducedTy::Other(_) | ReducedTy::Param,
|
||||
ReducedTy::OrderedFields(..) | ReducedTy::Ref(_) | ReducedTy::Other(_) | ReducedTy::Param,
|
||||
)
|
||||
| (
|
||||
ReducedTy::UnorderedFields(_) | ReducedTy::Param,
|
||||
@ -269,7 +273,8 @@ enum ReducedTy<'tcx> {
|
||||
TypeErasure,
|
||||
/// The type is a struct containing either zero non-zero sized fields, or multiple non-zero
|
||||
/// sized fields with a defined order.
|
||||
OrderedFields(Ty<'tcx>),
|
||||
/// The second value is the first non-zero sized type.
|
||||
OrderedFields(Ty<'tcx>, Option<Ty<'tcx>>),
|
||||
/// The type is a struct containing multiple non-zero sized fields with no defined order.
|
||||
UnorderedFields(Ty<'tcx>),
|
||||
/// The type is a reference to the contained type.
|
||||
@ -294,7 +299,7 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
|
||||
ty::Tuple(args) => {
|
||||
let mut iter = args.iter();
|
||||
let Some(sized_ty) = iter.find(|&ty| !is_zero_sized_ty(cx, ty)) else {
|
||||
return ReducedTy::OrderedFields(ty);
|
||||
return ReducedTy::OrderedFields(ty, None);
|
||||
};
|
||||
if iter.all(|ty| is_zero_sized_ty(cx, ty)) {
|
||||
ty = sized_ty;
|
||||
@ -316,7 +321,7 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
|
||||
continue;
|
||||
}
|
||||
if def.repr().inhibit_struct_field_reordering_opt() {
|
||||
ReducedTy::OrderedFields(ty)
|
||||
ReducedTy::OrderedFields(ty, Some(sized_ty))
|
||||
} else {
|
||||
ReducedTy::UnorderedFields(ty)
|
||||
}
|
||||
|
@ -109,6 +109,14 @@ fn main() {
|
||||
let _: Ty2<u32, u32> = transmute(value::<MaybeUninit<Ty2<u32, u32>>>()); // Ok
|
||||
|
||||
let _: Ty<&[u32]> = transmute::<&[u32], _>(value::<&Vec<u32>>()); // Ok
|
||||
|
||||
let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<Ty2<u32, u32>, u32>>()); // Ok
|
||||
let _: *const Ty2C<Ty2<u32, u32>, u32> = transmute(value::<*const Ty2<u32, u32>>()); // Ok
|
||||
let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<(), Ty2<u32, u32>>>()); // Ok
|
||||
let _: *const Ty2C<(), Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>()); // Ok
|
||||
|
||||
let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<u32, Ty2<u32, u32>>>()); // Err
|
||||
let _: *const Ty2C<u32, Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>()); // Err
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,8 +60,24 @@ LL | let _: Box<Ty2<u32, u32>> = transmute(value::<&'static mut Ty2<u32,
|
||||
|
|
||||
= note: two instances of the same generic type (`Ty2`) may have different layouts
|
||||
|
||||
error: transmute into `*const Ty2<u32, u32>` which has an undefined layout
|
||||
--> $DIR/transmute_undefined_repr.rs:118:39
|
||||
|
|
||||
LL | let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<u32, Ty2<u32, u32>>>()); // Err
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: the contained type `Ty2<u32, u32>` has an undefined layout
|
||||
|
||||
error: transmute from `*const Ty2<u32, u32>` which has an undefined layout
|
||||
--> $DIR/transmute_undefined_repr.rs:119:50
|
||||
|
|
||||
LL | let _: *const Ty2C<u32, Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>()); // Err
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: the contained type `Ty2<u32, u32>` has an undefined layout
|
||||
|
||||
error: transmute from `std::vec::Vec<Ty2<U, i32>>` to `std::vec::Vec<Ty2<T, u32>>`, both of which have an undefined layout
|
||||
--> $DIR/transmute_undefined_repr.rs:138:35
|
||||
--> $DIR/transmute_undefined_repr.rs:146:35
|
||||
|
|
||||
LL | let _: Vec<Ty2<T, u32>> = transmute(value::<Vec<Ty2<U, i32>>>()); // Err
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -69,12 +85,12 @@ LL | let _: Vec<Ty2<T, u32>> = transmute(value::<Vec<Ty2<U, i32>>>()); /
|
||||
= note: two instances of the same generic type (`Vec`) may have different layouts
|
||||
|
||||
error: transmute from `std::vec::Vec<Ty2<T, u32>>` to `std::vec::Vec<Ty2<U, i32>>`, both of which have an undefined layout
|
||||
--> $DIR/transmute_undefined_repr.rs:139:35
|
||||
--> $DIR/transmute_undefined_repr.rs:147:35
|
||||
|
|
||||
LL | let _: Vec<Ty2<U, i32>> = transmute(value::<Vec<Ty2<T, u32>>>()); // Err
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: two instances of the same generic type (`Vec`) may have different layouts
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
error: aborting due to 12 previous errors
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user