Skip to content

Commit e7d2393

Browse files
magurotunaflip1995
authored andcommitted
Move transmute_float_to_int to its own module
1 parent acedc7b commit e7d2393

File tree

2 files changed

+71
-44
lines changed

2 files changed

+71
-44
lines changed

clippy_lints/src/transmute/mod.rs

Lines changed: 5 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod crosspointer_transmute;
2+
mod transmute_float_to_int;
23
mod transmute_int_to_bool;
34
mod transmute_int_to_char;
45
mod transmute_int_to_float;
@@ -390,52 +391,12 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
390391
if triggered {
391392
return;
392393
}
394+
let triggered = transmute_float_to_int::check(cx, e, from_ty, to_ty, args, const_context);
395+
if triggered {
396+
return;
397+
}
393398

394399
match (&from_ty.kind(), &to_ty.kind()) {
395-
(ty::Float(float_ty), ty::Int(_) | ty::Uint(_)) if !const_context => span_lint_and_then(
396-
cx,
397-
TRANSMUTE_FLOAT_TO_INT,
398-
e.span,
399-
&format!("transmute from a `{}` to a `{}`", from_ty, to_ty),
400-
|diag| {
401-
let mut expr = &args[0];
402-
let mut arg = sugg::Sugg::hir(cx, expr, "..");
403-
404-
if let ExprKind::Unary(UnOp::Neg, inner_expr) = &expr.kind {
405-
expr = &inner_expr;
406-
}
407-
408-
if_chain! {
409-
// if the expression is a float literal and it is unsuffixed then
410-
// add a suffix so the suggestion is valid and unambiguous
411-
let op = format!("{}{}", arg, float_ty.name_str()).into();
412-
if let ExprKind::Lit(lit) = &expr.kind;
413-
if let ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) = lit.node;
414-
then {
415-
match arg {
416-
sugg::Sugg::MaybeParen(_) => arg = sugg::Sugg::MaybeParen(op),
417-
_ => arg = sugg::Sugg::NonParen(op)
418-
}
419-
}
420-
}
421-
422-
arg = sugg::Sugg::NonParen(format!("{}.to_bits()", arg.maybe_par()).into());
423-
424-
// cast the result of `to_bits` if `to_ty` is signed
425-
arg = if let ty::Int(int_ty) = to_ty.kind() {
426-
arg.as_ty(int_ty.name_str().to_string())
427-
} else {
428-
arg
429-
};
430-
431-
diag.span_suggestion(
432-
e.span,
433-
"consider using",
434-
arg.to_string(),
435-
Applicability::Unspecified,
436-
);
437-
},
438-
),
439400
(ty::Adt(from_adt, from_substs), ty::Adt(to_adt, to_substs)) => {
440401
if from_adt.did != to_adt.did ||
441402
!COLLECTIONS.iter().any(|path| match_def_path(cx, to_adt.did, path)) {
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
use super::TRANSMUTE_FLOAT_TO_INT;
2+
use crate::utils::{span_lint_and_then, sugg};
3+
use if_chain::if_chain;
4+
use rustc_ast as ast;
5+
use rustc_errors::Applicability;
6+
use rustc_hir::{Expr, ExprKind, UnOp};
7+
use rustc_lint::LateContext;
8+
use rustc_middle::ty;
9+
use rustc_middle::ty::Ty;
10+
11+
/// Checks for `transmute_float_to_int` lint.
12+
/// Returns `true` if it's triggered, otherwise returns `false`.
13+
pub(super) fn check<'tcx>(
14+
cx: &LateContext<'tcx>,
15+
e: &'tcx Expr<'_>,
16+
from_ty: Ty<'tcx>,
17+
to_ty: Ty<'tcx>,
18+
args: &'tcx [Expr<'_>],
19+
const_context: bool,
20+
) -> bool {
21+
match (&from_ty.kind(), &to_ty.kind()) {
22+
(ty::Float(float_ty), ty::Int(_) | ty::Uint(_)) if !const_context => {
23+
span_lint_and_then(
24+
cx,
25+
TRANSMUTE_FLOAT_TO_INT,
26+
e.span,
27+
&format!("transmute from a `{}` to a `{}`", from_ty, to_ty),
28+
|diag| {
29+
let mut expr = &args[0];
30+
let mut arg = sugg::Sugg::hir(cx, expr, "..");
31+
32+
if let ExprKind::Unary(UnOp::Neg, inner_expr) = &expr.kind {
33+
expr = &inner_expr;
34+
}
35+
36+
if_chain! {
37+
// if the expression is a float literal and it is unsuffixed then
38+
// add a suffix so the suggestion is valid and unambiguous
39+
let op = format!("{}{}", arg, float_ty.name_str()).into();
40+
if let ExprKind::Lit(lit) = &expr.kind;
41+
if let ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) = lit.node;
42+
then {
43+
match arg {
44+
sugg::Sugg::MaybeParen(_) => arg = sugg::Sugg::MaybeParen(op),
45+
_ => arg = sugg::Sugg::NonParen(op)
46+
}
47+
}
48+
}
49+
50+
arg = sugg::Sugg::NonParen(format!("{}.to_bits()", arg.maybe_par()).into());
51+
52+
// cast the result of `to_bits` if `to_ty` is signed
53+
arg = if let ty::Int(int_ty) = to_ty.kind() {
54+
arg.as_ty(int_ty.name_str().to_string())
55+
} else {
56+
arg
57+
};
58+
59+
diag.span_suggestion(e.span, "consider using", arg.to_string(), Applicability::Unspecified);
60+
},
61+
);
62+
true
63+
},
64+
_ => false,
65+
}
66+
}

0 commit comments

Comments
 (0)