Lint transmute::<&[u8], &str>

This commit is contained in:
sinkuu 2017-10-29 10:27:45 +09:00
parent fcebd5ce0c
commit 7fa27d9387
3 changed files with 74 additions and 4 deletions

View file

@ -88,7 +88,7 @@ declare_lint! {
/// ```rust
/// let _: char = std::mem::transmute(x); // where x: u32
/// // should be:
/// let _: Option<char> = std::char::from_u32(x);
/// let _ = std::char::from_u32(x).unwrap();
/// ```
declare_lint! {
pub TRANSMUTE_INT_TO_CHAR,
@ -96,6 +96,24 @@ declare_lint! {
"transmutes from an integer to a `char`"
}
/// **What it does:** Checks for transmutes from a `&[u8] to a `&str`.
///
/// **Why is this bad?** Not every byte slice is a valid UTF-8 string.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// let _: &str = std::mem::transmute(b); // where b: &[u8]
/// // should be:
/// let _ = std::str::from_utf8(b).unwrap();
/// ```
declare_lint! {
pub TRANSMUTE_BYTES_TO_STR,
Warn,
"transmutes from a `&[u8]` to a `&str`"
}
/// **What it does:** Checks for transmutes from an integer to a `bool`.
///
/// **Why is this bad?** This might result in an invalid in-memory representation of a `bool`.
@ -142,6 +160,7 @@ impl LintPass for Transmute {
USELESS_TRANSMUTE,
WRONG_TRANSMUTE,
TRANSMUTE_INT_TO_CHAR,
TRANSMUTE_BYTES_TO_STR,
TRANSMUTE_INT_TO_BOOL,
TRANSMUTE_INT_TO_FLOAT
)
@ -254,9 +273,41 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute {
} else {
arg
};
db.span_suggestion(e.span, "consider using", format!("std::char::from_u32({})", arg.to_string()));
db.span_suggestion(e.span, "consider using", format!("std::char::from_u32({}).unwrap()", arg.to_string()));
}
),
(&ty::TyRef(_, ref ref_from), &ty::TyRef(_, ref ref_to)) => {
if_chain! {
if let (&ty::TySlice(slice_ty), &ty::TyStr) = (&ref_from.ty.sty, &ref_to.ty.sty);
if let ty::TyUint(ast::UintTy::U8) = slice_ty.sty;
if ref_from.mutbl == ref_to.mutbl;
then {
let postfix = if ref_from.mutbl == Mutability::MutMutable {
"_mut"
} else {
""
};
span_lint_and_then(
cx,
TRANSMUTE_BYTES_TO_STR,
e.span,
&format!("transmute from a `{}` to a `{}`", from_ty, to_ty),
|db| {
db.span_suggestion(
e.span,
"consider using",
format!(
"std::str::from_utf8{}({}).unwrap()",
postfix,
snippet(cx, args[0].span, ".."),
),
);
}
)
}
}
},
(&ty::TyInt(ast::IntTy::I8), &ty::TyBool) |
(&ty::TyUint(ast::UintTy::U8), &ty::TyBool) => span_lint_and_then(
cx,