]> git.proxmox.com Git - rustc.git/blobdiff - src/tools/clippy/clippy_lints/src/methods/uninit_assumed_init.rs
Merge tag 'debian/1.52.1+dfsg1-1_exp2' into proxmox/buster
[rustc.git] / src / tools / clippy / clippy_lints / src / methods / uninit_assumed_init.rs
diff --git a/src/tools/clippy/clippy_lints/src/methods/uninit_assumed_init.rs b/src/tools/clippy/clippy_lints/src/methods/uninit_assumed_init.rs
new file mode 100644 (file)
index 0000000..798b661
--- /dev/null
@@ -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,
+    }
+}