Fix wrong suggestion in TRANSMUTE_PTR_TO_REF with lts

This commit is contained in:
mcarton 2016-09-19 17:59:12 +02:00
parent 5f1120b346
commit f74dcaac0c
No known key found for this signature in database
GPG key ID: 5E427C794CBA45E8
2 changed files with 47 additions and 8 deletions

View file

@ -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()
}

View file

@ -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() { }