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