mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 09:14:20 +00:00
Auto merge of #8440 - Jarcho:transmute_undefined, r=Manishearth
Some more fixes for `transmute_undefined_repr` changelog: Fix transmuting a struct containing a pointer into a pointer in `transmute_undefined_repr` changelog: Allow various forms of type erasure in `transmute_undefined_repr`
This commit is contained in:
commit
29ee5e25d1
@ -1,11 +1,11 @@
|
|||||||
use clippy_utils::diagnostics::span_lint;
|
use clippy_utils::diagnostics::span_lint;
|
||||||
use clippy_utils::is_hir_ty_cfg_dependant;
|
use clippy_utils::is_hir_ty_cfg_dependant;
|
||||||
|
use clippy_utils::ty::is_c_void;
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use rustc_hir::{Expr, ExprKind, GenericArg};
|
use rustc_hir::{Expr, ExprKind, GenericArg};
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::layout::LayoutOf;
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
use rustc_span::symbol::sym;
|
|
||||||
|
|
||||||
use super::CAST_PTR_ALIGNMENT;
|
use super::CAST_PTR_ALIGNMENT;
|
||||||
|
|
||||||
@ -62,19 +62,3 @@ fn lint_cast_ptr_alignment<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, cast_f
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the given type is either `core::ffi::c_void` or
|
|
||||||
/// one of the platform specific `libc::<platform>::c_void` of libc.
|
|
||||||
fn is_c_void(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
|
|
||||||
if let ty::Adt(adt, _) = ty.kind() {
|
|
||||||
let names = cx.get_def_path(adt.did);
|
|
||||||
|
|
||||||
if names.is_empty() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if names[0] == sym::libc || names[0] == sym::core && *names.last().unwrap() == sym!(c_void) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use super::TRANSMUTE_UNDEFINED_REPR;
|
use super::TRANSMUTE_UNDEFINED_REPR;
|
||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
|
use clippy_utils::ty::is_c_void;
|
||||||
use rustc_hir::Expr;
|
use rustc_hir::Expr;
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
use rustc_middle::ty::subst::{GenericArg, Subst};
|
use rustc_middle::ty::subst::{GenericArg, Subst};
|
||||||
@ -18,33 +19,55 @@ pub(super) fn check<'tcx>(
|
|||||||
|
|
||||||
while from_ty != to_ty {
|
while from_ty != to_ty {
|
||||||
match reduce_refs(cx, e.span, from_ty, to_ty) {
|
match reduce_refs(cx, e.span, from_ty, to_ty) {
|
||||||
ReducedTys::FromFatPtr { unsized_ty, .. } => {
|
ReducedTys::FromFatPtr {
|
||||||
span_lint_and_then(
|
unsized_ty,
|
||||||
cx,
|
to_ty: to_sub_ty,
|
||||||
TRANSMUTE_UNDEFINED_REPR,
|
} => match reduce_ty(cx, to_sub_ty) {
|
||||||
e.span,
|
ReducedTy::IntArray | ReducedTy::TypeErasure => break,
|
||||||
&format!("transmute from `{}` which has an undefined layout", from_ty_orig),
|
ReducedTy::Ref(to_sub_ty) => {
|
||||||
|diag| {
|
from_ty = unsized_ty;
|
||||||
if from_ty_orig.peel_refs() != unsized_ty {
|
to_ty = to_sub_ty;
|
||||||
diag.note(&format!("the contained type `&{}` has an undefined layout", unsized_ty));
|
continue;
|
||||||
}
|
},
|
||||||
},
|
_ => {
|
||||||
);
|
span_lint_and_then(
|
||||||
return true;
|
cx,
|
||||||
|
TRANSMUTE_UNDEFINED_REPR,
|
||||||
|
e.span,
|
||||||
|
&format!("transmute from `{}` which has an undefined layout", from_ty_orig),
|
||||||
|
|diag| {
|
||||||
|
if from_ty_orig.peel_refs() != unsized_ty {
|
||||||
|
diag.note(&format!("the contained type `&{}` has an undefined layout", unsized_ty));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
ReducedTys::ToFatPtr { unsized_ty, .. } => {
|
ReducedTys::ToFatPtr {
|
||||||
span_lint_and_then(
|
unsized_ty,
|
||||||
cx,
|
from_ty: from_sub_ty,
|
||||||
TRANSMUTE_UNDEFINED_REPR,
|
} => match reduce_ty(cx, from_sub_ty) {
|
||||||
e.span,
|
ReducedTy::IntArray | ReducedTy::TypeErasure => break,
|
||||||
&format!("transmute to `{}` which has an undefined layout", to_ty_orig),
|
ReducedTy::Ref(from_sub_ty) => {
|
||||||
|diag| {
|
from_ty = from_sub_ty;
|
||||||
if to_ty_orig.peel_refs() != unsized_ty {
|
to_ty = unsized_ty;
|
||||||
diag.note(&format!("the contained type `&{}` has an undefined layout", unsized_ty));
|
continue;
|
||||||
}
|
},
|
||||||
},
|
_ => {
|
||||||
);
|
span_lint_and_then(
|
||||||
return true;
|
cx,
|
||||||
|
TRANSMUTE_UNDEFINED_REPR,
|
||||||
|
e.span,
|
||||||
|
&format!("transmute to `{}` which has an undefined layout", to_ty_orig),
|
||||||
|
|diag| {
|
||||||
|
if to_ty_orig.peel_refs() != unsized_ty {
|
||||||
|
diag.note(&format!("the contained type `&{}` has an undefined layout", unsized_ty));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
ReducedTys::ToPtr {
|
ReducedTys::ToPtr {
|
||||||
from_ty: from_sub_ty,
|
from_ty: from_sub_ty,
|
||||||
@ -100,7 +123,8 @@ pub(super) fn check<'tcx>(
|
|||||||
from_ty: from_sub_ty,
|
from_ty: from_sub_ty,
|
||||||
to_ty: to_sub_ty,
|
to_ty: to_sub_ty,
|
||||||
} => match (reduce_ty(cx, from_sub_ty), reduce_ty(cx, to_sub_ty)) {
|
} => match (reduce_ty(cx, from_sub_ty), reduce_ty(cx, to_sub_ty)) {
|
||||||
(ReducedTy::IntArray, _) | (_, ReducedTy::IntArray) => return false,
|
(ReducedTy::IntArray | ReducedTy::TypeErasure, _)
|
||||||
|
| (_, ReducedTy::IntArray | ReducedTy::TypeErasure) => return false,
|
||||||
(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 => {
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
@ -182,13 +206,14 @@ pub(super) fn check<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum ReducedTys<'tcx> {
|
enum ReducedTys<'tcx> {
|
||||||
FromFatPtr { unsized_ty: Ty<'tcx> },
|
FromFatPtr { unsized_ty: Ty<'tcx>, to_ty: Ty<'tcx> },
|
||||||
ToFatPtr { unsized_ty: Ty<'tcx> },
|
ToFatPtr { unsized_ty: Ty<'tcx>, from_ty: Ty<'tcx> },
|
||||||
ToPtr { from_ty: Ty<'tcx>, to_ty: Ty<'tcx> },
|
ToPtr { from_ty: Ty<'tcx>, to_ty: Ty<'tcx> },
|
||||||
FromPtr { from_ty: Ty<'tcx>, to_ty: Ty<'tcx> },
|
FromPtr { from_ty: Ty<'tcx>, to_ty: Ty<'tcx> },
|
||||||
Other { from_ty: Ty<'tcx>, to_ty: Ty<'tcx> },
|
Other { from_ty: Ty<'tcx>, to_ty: Ty<'tcx> },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Remove references so long as both types are references.
|
||||||
fn reduce_refs<'tcx>(
|
fn reduce_refs<'tcx>(
|
||||||
cx: &LateContext<'tcx>,
|
cx: &LateContext<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -208,12 +233,12 @@ fn reduce_refs<'tcx>(
|
|||||||
(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. }), _)
|
(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. }), _)
|
||||||
if !unsized_ty.is_sized(cx.tcx.at(span), cx.param_env) =>
|
if !unsized_ty.is_sized(cx.tcx.at(span), cx.param_env) =>
|
||||||
{
|
{
|
||||||
ReducedTys::FromFatPtr { unsized_ty }
|
ReducedTys::FromFatPtr { unsized_ty, to_ty }
|
||||||
},
|
},
|
||||||
(_, ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. }))
|
(_, ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. }))
|
||||||
if !unsized_ty.is_sized(cx.tcx.at(span), cx.param_env) =>
|
if !unsized_ty.is_sized(cx.tcx.at(span), cx.param_env) =>
|
||||||
{
|
{
|
||||||
ReducedTys::ToFatPtr { unsized_ty }
|
ReducedTys::ToFatPtr { unsized_ty, from_ty }
|
||||||
},
|
},
|
||||||
(ty::Ref(_, from_ty, _) | ty::RawPtr(TypeAndMut { ty: from_ty, .. }), _) => {
|
(ty::Ref(_, from_ty, _) | ty::RawPtr(TypeAndMut { ty: from_ty, .. }), _) => {
|
||||||
ReducedTys::FromPtr { from_ty, to_ty }
|
ReducedTys::FromPtr { from_ty, to_ty }
|
||||||
@ -227,13 +252,23 @@ fn reduce_refs<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum ReducedTy<'tcx> {
|
enum ReducedTy<'tcx> {
|
||||||
|
/// The type can be used for type erasure.
|
||||||
|
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>),
|
OrderedFields(Ty<'tcx>),
|
||||||
|
/// The type is a struct containing multiple non-zero sized fields with no defined order.
|
||||||
UnorderedFields(Ty<'tcx>),
|
UnorderedFields(Ty<'tcx>),
|
||||||
|
/// The type is a reference to the contained type.
|
||||||
Ref(Ty<'tcx>),
|
Ref(Ty<'tcx>),
|
||||||
Other(Ty<'tcx>),
|
/// The type is an array of a primitive integer type. These can be used as storage for a value
|
||||||
|
/// of another type.
|
||||||
IntArray,
|
IntArray,
|
||||||
|
/// Any other type.
|
||||||
|
Other(Ty<'tcx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reduce structs containing a single non-zero sized field to it's contained type.
|
||||||
fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx> {
|
fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx> {
|
||||||
loop {
|
loop {
|
||||||
ty = cx.tcx.try_normalize_erasing_regions(cx.param_env, ty).unwrap_or(ty);
|
ty = cx.tcx.try_normalize_erasing_regions(cx.param_env, ty).unwrap_or(ty);
|
||||||
@ -243,6 +278,7 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
|
|||||||
ty = sub_ty;
|
ty = sub_ty;
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
|
ty::Tuple(args) if args.is_empty() => ReducedTy::TypeErasure,
|
||||||
ty::Tuple(args) => {
|
ty::Tuple(args) => {
|
||||||
let mut iter = args.iter().map(GenericArg::expect_ty);
|
let mut iter = args.iter().map(GenericArg::expect_ty);
|
||||||
let Some(sized_ty) = iter.find(|ty| !is_zero_sized_ty(cx, ty)) else {
|
let Some(sized_ty) = iter.find(|ty| !is_zero_sized_ty(cx, ty)) else {
|
||||||
@ -261,7 +297,7 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|f| cx.tcx.type_of(f.did).subst(cx.tcx, substs));
|
.map(|f| cx.tcx.type_of(f.did).subst(cx.tcx, substs));
|
||||||
let Some(sized_ty) = iter.find(|ty| !is_zero_sized_ty(cx, ty)) else {
|
let Some(sized_ty) = iter.find(|ty| !is_zero_sized_ty(cx, ty)) else {
|
||||||
return ReducedTy::OrderedFields(ty);
|
return ReducedTy::TypeErasure;
|
||||||
};
|
};
|
||||||
if iter.all(|ty| is_zero_sized_ty(cx, ty)) {
|
if iter.all(|ty| is_zero_sized_ty(cx, ty)) {
|
||||||
ty = sized_ty;
|
ty = sized_ty;
|
||||||
@ -273,7 +309,12 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
|
|||||||
ReducedTy::UnorderedFields(ty)
|
ReducedTy::UnorderedFields(ty)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ty::Ref(..) | ty::RawPtr(_) => ReducedTy::Ref(ty),
|
ty::Adt(def, _) if def.is_enum() && (def.variants.is_empty() || is_c_void(cx, ty)) => {
|
||||||
|
ReducedTy::TypeErasure
|
||||||
|
},
|
||||||
|
ty::Foreign(_) => ReducedTy::TypeErasure,
|
||||||
|
ty::Ref(_, ty, _) => ReducedTy::Ref(ty),
|
||||||
|
ty::RawPtr(ty) => ReducedTy::Ref(ty.ty),
|
||||||
_ => ReducedTy::Other(ty),
|
_ => ReducedTy::Other(ty),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![feature(control_flow_enum)]
|
#![feature(control_flow_enum)]
|
||||||
#![feature(let_else)]
|
#![feature(let_else)]
|
||||||
|
#![feature(let_chains)]
|
||||||
#![feature(once_cell)]
|
#![feature(once_cell)]
|
||||||
#![feature(rustc_private)]
|
#![feature(rustc_private)]
|
||||||
#![recursion_limit = "512"]
|
#![recursion_limit = "512"]
|
||||||
|
@ -572,3 +572,17 @@ pub fn get_discriminant_value(tcx: TyCtxt<'_>, adt: &'_ AdtDef, i: VariantIdx) -
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if the given type is either `core::ffi::c_void`, `std::os::raw::c_void`, or one of the
|
||||||
|
/// platform specific `libc::<platform>::c_void` types in libc.
|
||||||
|
pub fn is_c_void(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
|
||||||
|
if let ty::Adt(adt, _) = ty.kind()
|
||||||
|
&& let &[krate, .., name] = &*cx.get_def_path(adt.did)
|
||||||
|
&& let sym::libc | sym::core | sym::std = krate
|
||||||
|
&& name.as_str() == "c_void"
|
||||||
|
{
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
#![warn(clippy::transmute_undefined_repr)]
|
#![warn(clippy::transmute_undefined_repr)]
|
||||||
#![allow(clippy::unit_arg)]
|
#![allow(clippy::unit_arg, clippy::transmute_ptr_to_ref)]
|
||||||
|
|
||||||
|
use core::ffi::c_void;
|
||||||
|
use core::mem::{size_of, transmute};
|
||||||
|
|
||||||
fn value<T>() -> T {
|
fn value<T>() -> T {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
@ -14,35 +17,75 @@ struct Ty2C<T, U>(T, U);
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let _: () = core::mem::transmute(value::<Empty>());
|
let _: () = transmute(value::<Empty>());
|
||||||
let _: Empty = core::mem::transmute(value::<()>());
|
let _: Empty = transmute(value::<()>());
|
||||||
|
|
||||||
let _: Ty<u32> = core::mem::transmute(value::<u32>());
|
let _: Ty<u32> = transmute(value::<u32>());
|
||||||
let _: Ty<u32> = core::mem::transmute(value::<u32>());
|
let _: Ty<u32> = transmute(value::<u32>());
|
||||||
|
|
||||||
let _: Ty2C<u32, i32> = core::mem::transmute(value::<Ty2<u32, i32>>()); // Lint, Ty2 is unordered
|
let _: Ty2C<u32, i32> = transmute(value::<Ty2<u32, i32>>()); // Lint, Ty2 is unordered
|
||||||
let _: Ty2<u32, i32> = core::mem::transmute(value::<Ty2C<u32, i32>>()); // Lint, Ty2 is unordered
|
let _: Ty2<u32, i32> = transmute(value::<Ty2C<u32, i32>>()); // Lint, Ty2 is unordered
|
||||||
|
|
||||||
let _: Ty2<u32, i32> = core::mem::transmute(value::<Ty<Ty2<u32, i32>>>()); // Ok, Ty2 types are the same
|
let _: Ty2<u32, i32> = transmute(value::<Ty<Ty2<u32, i32>>>()); // Ok, Ty2 types are the same
|
||||||
let _: Ty<Ty2<u32, i32>> = core::mem::transmute(value::<Ty2<u32, i32>>()); // Ok, Ty2 types are the same
|
let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, i32>>()); // Ok, Ty2 types are the same
|
||||||
|
|
||||||
let _: Ty2<u32, f32> = core::mem::transmute(value::<Ty<Ty2<u32, i32>>>()); // Lint, different Ty2 instances
|
let _: Ty2<u32, f32> = transmute(value::<Ty<Ty2<u32, i32>>>()); // Lint, different Ty2 instances
|
||||||
let _: Ty<Ty2<u32, i32>> = core::mem::transmute(value::<Ty2<u32, f32>>()); // Lint, different Ty2 instances
|
let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, f32>>()); // Lint, different Ty2 instances
|
||||||
|
|
||||||
let _: Ty<&()> = core::mem::transmute(value::<&()>());
|
let _: Ty<&()> = transmute(value::<&()>());
|
||||||
let _: &() = core::mem::transmute(value::<Ty<&()>>());
|
let _: &() = transmute(value::<Ty<&()>>());
|
||||||
|
|
||||||
let _: &Ty2<u32, f32> = core::mem::transmute(value::<Ty<&Ty2<u32, i32>>>()); // Lint, different Ty2 instances
|
let _: &Ty2<u32, f32> = transmute(value::<Ty<&Ty2<u32, i32>>>()); // Lint, different Ty2 instances
|
||||||
let _: Ty<&Ty2<u32, i32>> = core::mem::transmute(value::<&Ty2<u32, f32>>()); // Lint, different Ty2 instances
|
let _: Ty<&Ty2<u32, i32>> = transmute(value::<&Ty2<u32, f32>>()); // Lint, different Ty2 instances
|
||||||
|
|
||||||
let _: Ty<usize> = core::mem::transmute(value::<&Ty2<u32, i32>>()); // Ok, pointer to usize conversion
|
let _: Ty<usize> = transmute(value::<&Ty2<u32, i32>>()); // Ok, pointer to usize conversion
|
||||||
let _: &Ty2<u32, i32> = core::mem::transmute(value::<Ty<usize>>()); // Ok, pointer to usize conversion
|
let _: &Ty2<u32, i32> = transmute(value::<Ty<usize>>()); // Ok, pointer to usize conversion
|
||||||
|
|
||||||
let _: Ty<[u8; 8]> = core::mem::transmute(value::<Ty2<u32, i32>>()); // Ok, transmute to byte array
|
let _: Ty<[u8; 8]> = transmute(value::<Ty2<u32, i32>>()); // Ok, transmute to byte array
|
||||||
let _: Ty2<u32, i32> = core::mem::transmute(value::<Ty<[u8; 8]>>()); // Ok, transmute from byte array
|
let _: Ty2<u32, i32> = transmute(value::<Ty<[u8; 8]>>()); // Ok, transmute from byte array
|
||||||
|
|
||||||
// issue #8417
|
// issue #8417
|
||||||
let _: Ty2C<Ty2<u32, i32>, ()> = core::mem::transmute(value::<Ty2<u32, i32>>()); // Ok, Ty2 types are the same
|
let _: Ty2C<Ty2<u32, i32>, ()> = transmute(value::<Ty2<u32, i32>>()); // Ok, Ty2 types are the same
|
||||||
let _: Ty2<u32, i32> = core::mem::transmute(value::<Ty2C<Ty2<u32, i32>, ()>>()); // Ok, Ty2 types are the same
|
let _: Ty2<u32, i32> = transmute(value::<Ty2C<Ty2<u32, i32>, ()>>()); // Ok, Ty2 types are the same
|
||||||
|
|
||||||
|
let _: &'static mut Ty2<u32, u32> = transmute(value::<Box<Ty2<u32, u32>>>()); // Ok, Ty2 types are the same
|
||||||
|
let _: Box<Ty2<u32, u32>> = transmute(value::<&'static mut Ty2<u32, u32>>()); // Ok, Ty2 types are the same
|
||||||
|
let _: *mut Ty2<u32, u32> = transmute(value::<Box<Ty2<u32, u32>>>()); // Ok, Ty2 types are the same
|
||||||
|
let _: Box<Ty2<u32, u32>> = transmute(value::<*mut Ty2<u32, u32>>()); // Ok, Ty2 types are the same
|
||||||
|
|
||||||
|
let _: &'static mut Ty2<u32, f32> = transmute(value::<Box<Ty2<u32, u32>>>()); // Lint, different Ty2 instances
|
||||||
|
let _: Box<Ty2<u32, u32>> = transmute(value::<&'static mut Ty2<u32, f32>>()); // Lint, different Ty2 instances
|
||||||
|
|
||||||
|
let _: *const () = transmute(value::<Ty<&Ty2<u32, f32>>>()); // Ok, type erasure
|
||||||
|
let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const ()>()); // Ok, reverse type erasure
|
||||||
|
|
||||||
|
let _: *const c_void = transmute(value::<Ty<&Ty2<u32, f32>>>()); // Ok, type erasure
|
||||||
|
let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const c_void>()); // Ok, reverse type erasure
|
||||||
|
|
||||||
|
enum Erase {}
|
||||||
|
let _: *const Erase = transmute(value::<Ty<&Ty2<u32, f32>>>()); // Ok, type erasure
|
||||||
|
let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const Erase>()); // Ok, reverse type erasure
|
||||||
|
|
||||||
|
struct Erase2(
|
||||||
|
[u8; 0],
|
||||||
|
core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
|
||||||
|
);
|
||||||
|
let _: *const Erase2 = transmute(value::<Ty<&Ty2<u32, f32>>>()); // Ok, type erasure
|
||||||
|
let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const Erase2>()); // Ok, reverse type erasure
|
||||||
|
|
||||||
|
let _: *const () = transmute(value::<&&[u8]>()); // Ok, type erasure
|
||||||
|
let _: &&[u8] = transmute(value::<*const ()>()); // Ok, reverse type erasure
|
||||||
|
|
||||||
|
let _: *mut c_void = transmute(value::<&mut &[u8]>()); // Ok, type erasure
|
||||||
|
let _: &mut &[u8] = transmute(value::<*mut c_void>()); // Ok, reverse type erasure
|
||||||
|
|
||||||
|
let _: [u8; size_of::<&[u8]>()] = transmute(value::<&[u8]>()); // Ok, transmute to byte array
|
||||||
|
let _: &[u8] = transmute(value::<[u8; size_of::<&[u8]>()]>()); // Ok, transmute from byte array
|
||||||
|
|
||||||
|
let _: [usize; 2] = transmute(value::<&[u8]>()); // Ok, transmute to int array
|
||||||
|
let _: &[u8] = transmute(value::<[usize; 2]>()); // Ok, transmute from int array
|
||||||
|
|
||||||
|
let _: *const [u8] = transmute(value::<Box<[u8]>>()); // Ok
|
||||||
|
let _: Box<[u8]> = transmute(value::<*mut [u8]>()); // Ok
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,44 +1,64 @@
|
|||||||
error: transmute from `Ty2<u32, i32>` which has an undefined layout
|
error: transmute from `Ty2<u32, i32>` which has an undefined layout
|
||||||
--> $DIR/transmute_undefined_repr.rs:23:33
|
--> $DIR/transmute_undefined_repr.rs:26:33
|
||||||
|
|
|
|
||||||
LL | let _: Ty2C<u32, i32> = core::mem::transmute(value::<Ty2<u32, i32>>()); // Lint, Ty2 is unordered
|
LL | let _: Ty2C<u32, i32> = transmute(value::<Ty2<u32, i32>>()); // Lint, Ty2 is unordered
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: `-D clippy::transmute-undefined-repr` implied by `-D warnings`
|
= note: `-D clippy::transmute-undefined-repr` implied by `-D warnings`
|
||||||
|
|
||||||
error: transmute into `Ty2<u32, i32>` which has an undefined layout
|
error: transmute into `Ty2<u32, i32>` which has an undefined layout
|
||||||
--> $DIR/transmute_undefined_repr.rs:24:32
|
--> $DIR/transmute_undefined_repr.rs:27:32
|
||||||
|
|
|
|
||||||
LL | let _: Ty2<u32, i32> = core::mem::transmute(value::<Ty2C<u32, i32>>()); // Lint, Ty2 is unordered
|
LL | let _: Ty2<u32, i32> = transmute(value::<Ty2C<u32, i32>>()); // Lint, Ty2 is unordered
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: transmute from `Ty<Ty2<u32, i32>>` to `Ty2<u32, f32>`, both of which have an undefined layout
|
error: transmute from `Ty<Ty2<u32, i32>>` to `Ty2<u32, f32>`, both of which have an undefined layout
|
||||||
--> $DIR/transmute_undefined_repr.rs:29:32
|
--> $DIR/transmute_undefined_repr.rs:32:32
|
||||||
|
|
|
|
||||||
LL | let _: Ty2<u32, f32> = core::mem::transmute(value::<Ty<Ty2<u32, i32>>>()); // Lint, different Ty2 instances
|
LL | let _: Ty2<u32, f32> = transmute(value::<Ty<Ty2<u32, i32>>>()); // Lint, different Ty2 instances
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: two instances of the same generic type (`Ty2`) may have different layouts
|
= note: two instances of the same generic type (`Ty2`) may have different layouts
|
||||||
|
|
||||||
error: transmute from `Ty2<u32, f32>` to `Ty<Ty2<u32, i32>>`, both of which have an undefined layout
|
error: transmute from `Ty2<u32, f32>` to `Ty<Ty2<u32, i32>>`, both of which have an undefined layout
|
||||||
--> $DIR/transmute_undefined_repr.rs:30:36
|
--> $DIR/transmute_undefined_repr.rs:33:36
|
||||||
|
|
|
|
||||||
LL | let _: Ty<Ty2<u32, i32>> = core::mem::transmute(value::<Ty2<u32, f32>>()); // Lint, different Ty2 instances
|
LL | let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, f32>>()); // Lint, different Ty2 instances
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: two instances of the same generic type (`Ty2`) may have different layouts
|
= note: two instances of the same generic type (`Ty2`) may have different layouts
|
||||||
|
|
||||||
error: transmute to `&Ty2<u32, f32>` which has an undefined layout
|
error: transmute from `Ty<&Ty2<u32, i32>>` to `&Ty2<u32, f32>`, both of which have an undefined layout
|
||||||
--> $DIR/transmute_undefined_repr.rs:35:33
|
--> $DIR/transmute_undefined_repr.rs:38:33
|
||||||
|
|
|
|
||||||
LL | let _: &Ty2<u32, f32> = core::mem::transmute(value::<Ty<&Ty2<u32, i32>>>()); // Lint, different Ty2 instances
|
LL | let _: &Ty2<u32, f32> = transmute(value::<Ty<&Ty2<u32, i32>>>()); // Lint, different Ty2 instances
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: transmute from `&Ty2<u32, f32>` which has an undefined layout
|
|
||||||
--> $DIR/transmute_undefined_repr.rs:36:37
|
|
||||||
|
|
|
|
||||||
LL | let _: Ty<&Ty2<u32, i32>> = core::mem::transmute(value::<&Ty2<u32, f32>>()); // Lint, different Ty2 instances
|
= note: two instances of the same generic type (`Ty2`) may have different layouts
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: transmute from `&Ty2<u32, f32>` to `Ty<&Ty2<u32, i32>>`, both of which have an undefined layout
|
||||||
|
--> $DIR/transmute_undefined_repr.rs:39:37
|
||||||
|
|
|
||||||
|
LL | let _: Ty<&Ty2<u32, i32>> = transmute(value::<&Ty2<u32, f32>>()); // Lint, different Ty2 instances
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: two instances of the same generic type (`Ty2`) may have different layouts
|
||||||
|
|
||||||
|
error: transmute from `std::boxed::Box<Ty2<u32, u32>>` to `&mut Ty2<u32, f32>`, both of which have an undefined layout
|
||||||
|
--> $DIR/transmute_undefined_repr.rs:56:45
|
||||||
|
|
|
||||||
|
LL | let _: &'static mut Ty2<u32, f32> = transmute(value::<Box<Ty2<u32, u32>>>()); // Lint, different Ty2 instances
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: two instances of the same generic type (`Ty2`) may have different layouts
|
||||||
|
|
||||||
|
error: transmute from `&mut Ty2<u32, f32>` to `std::boxed::Box<Ty2<u32, u32>>`, both of which have an undefined layout
|
||||||
|
--> $DIR/transmute_undefined_repr.rs:57:37
|
||||||
|
|
|
||||||
|
LL | let _: Box<Ty2<u32, u32>> = transmute(value::<&'static mut Ty2<u32, f32>>()); // Lint, different Ty2 instances
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: two instances of the same generic type (`Ty2`) may have different layouts
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user