Skip to content

Commit f50ded0

Browse files
committed
Catch pointer::cast too in cast_ptr_alignment
1 parent 8e5c5a6 commit f50ded0

File tree

3 files changed

+46
-7
lines changed

3 files changed

+46
-7
lines changed

clippy_lints/src/types.rs

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,12 +1637,8 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
16371637
return;
16381638
}
16391639
if let ExprKind::Cast(ref ex, cast_to) = expr.kind {
1640-
if let TyKind::Path(QPath::Resolved(_, path)) = cast_to.kind {
1641-
if let Res::Def(_, def_id) = path.res {
1642-
if cx.tcx.has_attr(def_id, sym::cfg) || cx.tcx.has_attr(def_id, sym::cfg_attr) {
1643-
return;
1644-
}
1645-
}
1640+
if is_hir_ty_cfg_dependant(cx, cast_to) {
1641+
return;
16461642
}
16471643
let (cast_from, cast_to) = (cx.typeck_results().expr_ty(ex), cx.typeck_results().expr_ty(expr));
16481644
lint_fn_to_numeric_cast(cx, expr, ex, cast_from, cast_to);
@@ -1691,6 +1687,21 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
16911687
lint_numeric_casts(cx, expr, ex, cast_from, cast_to);
16921688
}
16931689

1690+
lint_cast_ptr_alignment(cx, expr, cast_from, cast_to);
1691+
} else if let ExprKind::MethodCall(method_path, _, args, _) = expr.kind {
1692+
if method_path.ident.name != sym!(cast) {
1693+
return;
1694+
}
1695+
if_chain! {
1696+
if let Some(generic_args) = method_path.args;
1697+
if let [GenericArg::Type(cast_to)] = generic_args.args;
1698+
// There probably is no obvious reason to do this, just to be consistent with `as` cases.
1699+
if is_hir_ty_cfg_dependant(cx, cast_to);
1700+
then {
1701+
return;
1702+
}
1703+
}
1704+
let (cast_from, cast_to) = (cx.typeck_results().expr_ty(&args[0]), cx.typeck_results().expr_ty(expr));
16941705
lint_cast_ptr_alignment(cx, expr, cast_from, cast_to);
16951706
}
16961707
}
@@ -1714,6 +1725,18 @@ fn get_numeric_literal<'e>(expr: &'e Expr<'e>) -> Option<&'e Lit> {
17141725
}
17151726
}
17161727

1728+
fn is_hir_ty_cfg_dependant(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {
1729+
if_chain! {
1730+
if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind;
1731+
if let Res::Def(_, def_id) = path.res;
1732+
then {
1733+
cx.tcx.has_attr(def_id, sym::cfg) || cx.tcx.has_attr(def_id, sym::cfg_attr)
1734+
} else {
1735+
false
1736+
}
1737+
}
1738+
}
1739+
17171740
fn show_unnecessary_cast(cx: &LateContext<'_>, expr: &Expr<'_>, literal_str: &str, cast_from: Ty<'_>, cast_to: Ty<'_>) {
17181741
let literal_kind_name = if cast_from.is_integral() { "integer" } else { "float" };
17191742
span_lint_and_sugg(

tests/ui/cast_alignment.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ fn main() {
1212
(&1u8 as *const u8) as *const u16;
1313
(&mut 1u8 as *mut u8) as *mut u16;
1414

15+
// cast to more-strictly-aligned type, but with the `pointer::cast` function.
16+
(&1u8 as *const u8).cast::<u16>();
17+
(&mut 1u8 as *mut u8).cast::<u16>();
18+
1519
/* These should be ok */
1620

1721
// not a pointer type

tests/ui/cast_alignment.stderr

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,17 @@ error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1
1212
LL | (&mut 1u8 as *mut u8) as *mut u16;
1313
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1414

15-
error: aborting due to 2 previous errors
15+
error: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) (1 < 2 bytes)
16+
--> $DIR/cast_alignment.rs:15:5
17+
|
18+
LL | (&1u8 as *const u8).cast::<u16>();
19+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
20+
21+
error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes)
22+
--> $DIR/cast_alignment.rs:16:5
23+
|
24+
LL | (&mut 1u8 as *mut u8).cast::<u16>();
25+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26+
27+
error: aborting due to 4 previous errors
1628

0 commit comments

Comments
 (0)