diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 54a6a4cf934..acb8318970e 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -15,6 +15,7 @@ mod option_as_ref_deref; mod option_map_unwrap_or; mod skip_while_next; mod suspicious_map; +mod uninit_assumed_init; mod unnecessary_filter_map; mod unnecessary_lazy_eval; mod unwrap_used; @@ -1719,7 +1720,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { filter_map_identity::check(cx, expr, arg_lists[0], method_spans[0]); }, ["count", "map"] => suspicious_map::check(cx, expr), - ["assume_init"] => lint_maybe_uninit(cx, &arg_lists[0][0], expr), + ["assume_init"] => uninit_assumed_init::check(cx, &arg_lists[0][0], expr), ["unwrap_or", arith @ ("checked_add" | "checked_sub" | "checked_mul")] => { manual_saturating_arithmetic::lint(cx, expr, &arg_lists, &arith["checked_".len()..]) }, @@ -3548,34 +3549,6 @@ fn lint_into_iter(cx: &LateContext<'_>, expr: &hir::Expr<'_>, self_ref_ty: Ty<'_ } } -/// lint for `MaybeUninit::uninit().assume_init()` (we already have the latter) -fn lint_maybe_uninit(cx: &LateContext<'_>, expr: &hir::Expr<'_>, outer: &hir::Expr<'_>) { - if_chain! { - if let hir::ExprKind::Call(ref callee, ref args) = expr.kind; - if args.is_empty(); - if let hir::ExprKind::Path(ref path) = callee.kind; - if match_qpath(path, &paths::MEM_MAYBEUNINIT_UNINIT); - if !is_maybe_uninit_ty_valid(cx, cx.typeck_results().expr_ty_adjusted(outer)); - then { - span_lint( - cx, - UNINIT_ASSUMED_INIT, - outer.span, - "this call for this type may be undefined behavior" - ); - } - } -} - -fn is_maybe_uninit_ty_valid(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { - match ty.kind() { - ty::Array(ref component, _) => is_maybe_uninit_ty_valid(cx, component), - ty::Tuple(ref types) => types.types().all(|ty| is_maybe_uninit_ty_valid(cx, ty)), - ty::Adt(ref adt, _) => match_def_path(cx, adt.did, &paths::MEM_MAYBEUNINIT), - _ => false, - } -} - fn lint_map_collect( cx: &LateContext<'_>, expr: &hir::Expr<'_>, diff --git a/clippy_lints/src/methods/uninit_assumed_init.rs b/clippy_lints/src/methods/uninit_assumed_init.rs new file mode 100644 index 00000000000..798b66192c8 --- /dev/null +++ b/clippy_lints/src/methods/uninit_assumed_init.rs @@ -0,0 +1,35 @@ +use crate::utils::{match_def_path, match_qpath, paths, span_lint}; +use if_chain::if_chain; +use rustc_hir as hir; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, Ty}; + +use super::UNINIT_ASSUMED_INIT; + +/// lint for `MaybeUninit::uninit().assume_init()` (we already have the latter) +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, outer: &hir::Expr<'_>) { + if_chain! { + if let hir::ExprKind::Call(ref callee, ref args) = expr.kind; + if args.is_empty(); + if let hir::ExprKind::Path(ref path) = callee.kind; + if match_qpath(path, &paths::MEM_MAYBEUNINIT_UNINIT); + if !is_maybe_uninit_ty_valid(cx, cx.typeck_results().expr_ty_adjusted(outer)); + then { + span_lint( + cx, + UNINIT_ASSUMED_INIT, + outer.span, + "this call for this type may be undefined behavior" + ); + } + } +} + +fn is_maybe_uninit_ty_valid(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { + match ty.kind() { + ty::Array(ref component, _) => is_maybe_uninit_ty_valid(cx, component), + ty::Tuple(ref types) => types.types().all(|ty| is_maybe_uninit_ty_valid(cx, ty)), + ty::Adt(ref adt, _) => match_def_path(cx, adt.did, &paths::MEM_MAYBEUNINIT), + _ => false, + } +}