Skip to content

Commit

Permalink
Auto merge of #8564 - Jarcho:transmute_erase_regions, r=Alexendoo
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed May 31, 2022
2 parents 9add456 + 0c6ebf1 commit 7000e75
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 73 deletions.
1 change: 1 addition & 0 deletions clippy_lints/src/lib.register_all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
1 change: 1 addition & 0 deletions clippy_lints/src/lib.register_complexity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
1 change: 0 additions & 1 deletion clippy_lints/src/lib.register_nursery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
])
2 changes: 1 addition & 1 deletion clippy_lints/src/transmute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}

Expand Down
47 changes: 25 additions & 22 deletions clippy_lints/src/transmute/useless_transmute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand All @@ -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,
Expand All @@ -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(_)) => {
Expand Down
19 changes: 18 additions & 1 deletion tests/ui/transmute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ fn my_vec() -> MyVec<i32> {
#[allow(clippy::needless_lifetimes, clippy::transmute_ptr_to_ptr)]
#[warn(clippy::useless_transmute)]
unsafe fn _generic<'a, T, U: 'a>(t: &'a T) {
let _: &'a T = core::intrinsics::transmute(t);
// FIXME: should lint
// let _: &'a T = core::intrinsics::transmute(t);

let _: &'a U = core::intrinsics::transmute(t);

Expand Down Expand Up @@ -48,6 +49,22 @@ fn useless() {

let _ = (1 + 1_usize) as *const usize;
}

unsafe fn _f<'a, 'b>(x: &'a u32) -> &'b u32 {
std::mem::transmute(x)
}

unsafe fn _f2<'a, 'b>(x: *const (dyn Iterator<Item = u32> + 'a)) -> *const (dyn Iterator<Item = u32> + 'b) {
std::mem::transmute(x)
}

unsafe fn _f3<'a, 'b>(x: fn(&'a u32)) -> fn(&'b u32) {
std::mem::transmute(x)
}

unsafe fn _f4<'a, 'b>(x: std::borrow::Cow<'a, str>) -> std::borrow::Cow<'b, str> {
std::mem::transmute(x)
}
}

struct Usize(usize);
Expand Down
Loading

0 comments on commit 7000e75

Please sign in to comment.