Auto merge of #8564 - Jarcho:transmute_erase_regions, r=Alexendoo

Don't lint `useless_transmute` on types with erased regions

fixes #6356
fixes #3340
fixes #2906

This should get a proper fix at some point, but this at least gets the lint running on some types.

cc #5343

changelog: Don't lint `useless_transmute` on types with erased regions
This commit is contained in:
bors 2022-05-31 15:57:27 +00:00
commit 7000e758c1
8 changed files with 89 additions and 74 deletions

View file

@ -305,6 +305,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(transmute::TRANSMUTE_NUM_TO_BYTES),
LintId::of(transmute::TRANSMUTE_PTR_TO_REF),
LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE),
LintId::of(transmute::USELESS_TRANSMUTE),
LintId::of(transmute::WRONG_TRANSMUTE),
LintId::of(transmuting_null::TRANSMUTING_NULL),
LintId::of(types::BORROWED_BOX),

View file

@ -90,6 +90,7 @@ store.register_group(true, "clippy::complexity", Some("clippy_complexity"), 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::USELESS_TRANSMUTE),
LintId::of(types::BORROWED_BOX),
LintId::of(types::TYPE_COMPLEXITY),
LintId::of(types::VEC_BOX),

View file

@ -31,7 +31,6 @@ store.register_group(true, "clippy::nursery", Some("clippy_nursery"), vec![
LintId::of(trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS),
LintId::of(trait_bounds::TYPE_REPETITION_IN_BOUNDS),
LintId::of(transmute::TRANSMUTE_UNDEFINED_REPR),
LintId::of(transmute::USELESS_TRANSMUTE),
LintId::of(unused_rounding::UNUSED_ROUNDING),
LintId::of(use_self::USE_SELF),
])

View file

@ -59,7 +59,7 @@ declare_clippy_lint! {
/// ```
#[clippy::version = "pre 1.29.0"]
pub USELESS_TRANSMUTE,
nursery,
complexity,
"transmutes that have the same to and from types or could be a cast/coercion"
}

View file

@ -4,7 +4,7 @@ use clippy_utils::sugg;
use rustc_errors::Applicability;
use rustc_hir::Expr;
use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty};
use rustc_middle::ty::{self, Ty, TypeFoldable};
/// Checks for `useless_transmute` lint.
/// Returns `true` if it's triggered, otherwise returns `false`.
@ -16,7 +16,7 @@ pub(super) fn check<'tcx>(
arg: &'tcx Expr<'_>,
) -> bool {
match (&from_ty.kind(), &to_ty.kind()) {
_ if from_ty == to_ty => {
_ if from_ty == to_ty && !from_ty.has_erased_regions() => {
span_lint(
cx,
USELESS_TRANSMUTE,
@ -26,28 +26,31 @@ pub(super) fn check<'tcx>(
true
},
(ty::Ref(_, rty, rty_mutbl), ty::RawPtr(ptr_ty)) => {
span_lint_and_then(
cx,
USELESS_TRANSMUTE,
e.span,
"transmute from a reference to a pointer",
|diag| {
if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) {
let rty_and_mut = ty::TypeAndMut {
ty: *rty,
mutbl: *rty_mutbl,
};
// No way to give the correct suggestion here. Avoid linting for now.
if !rty.has_erased_regions() {
span_lint_and_then(
cx,
USELESS_TRANSMUTE,
e.span,
"transmute from a reference to a pointer",
|diag| {
if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) {
let rty_and_mut = ty::TypeAndMut {
ty: *rty,
mutbl: *rty_mutbl,
};
let sugg = if *ptr_ty == rty_and_mut {
arg.as_ty(to_ty)
} else {
arg.as_ty(cx.tcx.mk_ptr(rty_and_mut)).as_ty(to_ty)
};
let sugg = if *ptr_ty == rty_and_mut {
arg.as_ty(to_ty)
} else {
arg.as_ty(cx.tcx.mk_ptr(rty_and_mut)).as_ty(to_ty)
};
diag.span_suggestion(e.span, "try", sugg.to_string(), Applicability::Unspecified);
}
},
);
diag.span_suggestion(e.span, "try", sugg.to_string(), Applicability::Unspecified);
}
},
);
}
true
},
(ty::Int(_) | ty::Uint(_), ty::RawPtr(_)) => {