Don't lint lifetime-only transmutes

This commit is contained in:
Devon Hollowood 2018-05-14 12:24:31 -05:00
parent 400aab9232
commit 2a606b5220
2 changed files with 28 additions and 19 deletions

View File

@ -192,7 +192,7 @@ declare_clippy_lint! {
declare_clippy_lint! { declare_clippy_lint! {
pub TRANSMUTE_PTR_TO_PTR, pub TRANSMUTE_PTR_TO_PTR,
complexity, complexity,
"transmutes from a pointer to a reference type" "transmutes from a pointer to a pointer / a reference to a reference"
} }
pub struct Transmute; pub struct Transmute;
@ -363,23 +363,26 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute {
} }
) )
} else { } else {
span_lint_and_then( // In this case they differ only in lifetime
cx, if ty_from != ty_to {
TRANSMUTE_PTR_TO_PTR, span_lint_and_then(
e.span, cx,
"transmute from a reference to a reference", TRANSMUTE_PTR_TO_PTR,
|db| if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) { e.span,
let ty_from_and_mut = ty::TypeAndMut { ty: ty_from, mutbl: from_mutbl }; "transmute from a reference to a reference",
let ty_to_and_mut = ty::TypeAndMut { ty: ty_to, mutbl: to_mutbl }; |db| if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) {
let sugg_paren = arg.as_ty(cx.tcx.mk_ptr(ty_from_and_mut)).as_ty(cx.tcx.mk_ptr(ty_to_and_mut)); let ty_from_and_mut = ty::TypeAndMut { ty: ty_from, mutbl: from_mutbl };
let sugg = if to_mutbl == Mutability::MutMutable { let ty_to_and_mut = ty::TypeAndMut { ty: ty_to, mutbl: to_mutbl };
sugg_paren.mut_addr_deref() let sugg_paren = arg.as_ty(cx.tcx.mk_ptr(ty_from_and_mut)).as_ty(cx.tcx.mk_ptr(ty_to_and_mut));
} else { let sugg = if to_mutbl == Mutability::MutMutable {
sugg_paren.addr_deref() sugg_paren.mut_addr_deref()
}; } else {
db.span_suggestion(e.span, "try", sugg.to_string()); sugg_paren.addr_deref()
}, };
) db.span_suggestion(e.span, "try", sugg.to_string());
},
)
}
} }
} }
}, },

View File

@ -152,11 +152,17 @@ fn transmute_ptr_to_ptr() {
let _: &f32 = std::mem::transmute(&1u32); let _: &f32 = std::mem::transmute(&1u32);
let _: &mut f32 = std::mem::transmute(&mut 1u32); let _: &mut f32 = std::mem::transmute(&mut 1u32);
} }
// These should be fine // These should be fine:
// Recommendations for solving the above; if these break we need to update
// those suggestions
let _ = ptr as *const f32; let _ = ptr as *const f32;
let _ = mut_ptr as *mut f32; let _ = mut_ptr as *mut f32;
let _ = unsafe { &*(&1u32 as *const u32 as *const f32) }; let _ = unsafe { &*(&1u32 as *const u32 as *const f32) };
let _ = unsafe { &mut *(&mut 1u32 as *mut u32 as *mut f32) }; let _ = unsafe { &mut *(&mut 1u32 as *mut u32 as *mut f32) };
// This is just modifying the lifetime, and is one of the recommended uses
// of transmute
let n = 1u32;
let _ = unsafe { std::mem::transmute::<&'_ u32, &'static u32>(&n) };
} }
fn main() { } fn main() { }