mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-23 21:23:56 +00:00
Fix wrong suggestion in TRANSMUTE_PTR_TO_REF
with lts
This commit is contained in:
parent
5f1120b346
commit
f74dcaac0c
2 changed files with 47 additions and 8 deletions
|
@ -2,7 +2,7 @@ use rustc::lint::*;
|
|||
use rustc::ty::TypeVariants::{TyRawPtr, TyRef};
|
||||
use rustc::ty;
|
||||
use rustc::hir::*;
|
||||
use utils::{match_def_path, paths, span_lint, span_lint_and_then};
|
||||
use utils::{match_def_path, paths, span_lint, span_lint_and_then, snippet};
|
||||
use utils::sugg;
|
||||
|
||||
/// **What it does:** Checks for transmutes that can't ever be correct on any
|
||||
|
@ -87,7 +87,7 @@ impl LintPass for Transmute {
|
|||
impl LateLintPass for Transmute {
|
||||
fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
|
||||
if let ExprCall(ref path_expr, ref args) = e.node {
|
||||
if let ExprPath(None, _) = path_expr.node {
|
||||
if let ExprPath(None, ref path) = path_expr.node {
|
||||
let def_id = cx.tcx.expect_def(path_expr.id).def_id();
|
||||
|
||||
if match_def_path(cx, def_id, &paths::TRANSMUTE) {
|
||||
|
@ -170,11 +170,10 @@ impl LateLintPass for Transmute {
|
|||
("&*", "*const")
|
||||
};
|
||||
|
||||
|
||||
let arg = if from_pty.ty == to_rty.ty {
|
||||
arg
|
||||
} else {
|
||||
arg.as_ty(&format!("{} {}", cast, to_rty.ty))
|
||||
arg.as_ty(&format!("{} {}", cast, get_type_snippet(cx, path, to_rty.ty)))
|
||||
};
|
||||
|
||||
db.span_suggestion(e.span, "try", sugg::make_unop(deref, arg).to_string());
|
||||
|
@ -187,3 +186,19 @@ impl LateLintPass for Transmute {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the snippet of `Bar` in `…::transmute<Foo, &Bar>`. If that snippet is not available , use
|
||||
/// the type's `ToString` implementation. In weird cases it could lead to types with invalid `'_`
|
||||
/// lifetime, but it should be rare.
|
||||
fn get_type_snippet(cx: &LateContext, path: &Path, to_rty: ty::Ty) -> String {
|
||||
if_let_chain!{[
|
||||
let Some(seg) = path.segments.last(),
|
||||
let PathParameters::AngleBracketedParameters(ref ang) = seg.parameters,
|
||||
let Some(to_ty) = ang.types.get(1),
|
||||
let TyRptr(_, ref to_ty) = to_ty.node,
|
||||
], {
|
||||
return snippet(cx, to_ty.ty.span, &to_rty.to_string()).to_string();
|
||||
}}
|
||||
|
||||
to_rty.to_string()
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#![feature(plugin)]
|
||||
#![plugin(clippy)]
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
extern crate core;
|
||||
|
||||
use std::mem::transmute as my_transmute;
|
||||
|
@ -83,6 +85,31 @@ unsafe fn _ptr_to_ref<T, U>(p: *const T, m: *mut T, o: *const U, om: *mut U) {
|
|||
let _: &T = &*(om as *const T);
|
||||
}
|
||||
|
||||
#[deny(transmute_ptr_to_ref)]
|
||||
fn issue1231() {
|
||||
struct Foo<'a, T: 'a> {
|
||||
bar: &'a T,
|
||||
}
|
||||
|
||||
let raw = 0 as *const i32;
|
||||
let _: &Foo<u8> = unsafe { std::mem::transmute::<_, &Foo<_>>(raw) };
|
||||
//~^ ERROR transmute from a pointer type
|
||||
//~| HELP try
|
||||
//~| SUGGESTION unsafe { &*(raw as *const Foo<_>) };
|
||||
|
||||
let _: &Foo<&u8> = unsafe { std::mem::transmute::<_, &Foo<&_>>(raw) };
|
||||
//~^ ERROR transmute from a pointer type
|
||||
//~| HELP try
|
||||
//~| SUGGESTION unsafe { &*(raw as *const Foo<&_>) };
|
||||
|
||||
type Bar<'a> = &'a u8;
|
||||
let raw = 0 as *const i32;
|
||||
unsafe { std::mem::transmute::<_, Bar>(raw) };
|
||||
//~^ ERROR transmute from a pointer type
|
||||
//~| HELP try
|
||||
//~| SUGGESTION unsafe { &*(raw as *const u8) };
|
||||
}
|
||||
|
||||
#[deny(useless_transmute)]
|
||||
fn useless() {
|
||||
unsafe {
|
||||
|
@ -144,7 +171,4 @@ fn crosspointer() {
|
|||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
useless();
|
||||
crosspointer();
|
||||
}
|
||||
fn main() { }
|
||||
|
|
Loading…
Reference in a new issue