From dc4b6a94e8b0eb492e5858abdb75b15c82b91d7d Mon Sep 17 00:00:00 2001 From: 5225225 <5225225@mailbox.org> Date: Sun, 28 Aug 2022 23:24:27 +0100 Subject: [PATCH] Ignore invalid_value lint if mem_uninitialized would lint --- compiler/rustc_lint/src/builtin.rs | 273 ++--------- compiler/rustc_lint/src/lib.rs | 3 + compiler/rustc_lint/src/mem_uninitialized.rs | 233 +++++++++ src/test/ui/lint/uninitialized-zeroed.rs | 40 +- src/test/ui/lint/uninitialized-zeroed.stderr | 468 ++----------------- 5 files changed, 325 insertions(+), 692 deletions(-) create mode 100644 compiler/rustc_lint/src/mem_uninitialized.rs diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 3b9684b5536f0..a4261048d8d03 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2366,7 +2366,13 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { #[derive(Debug, Copy, Clone, PartialEq)] enum InitKind { Zeroed, - Uninit, + Uninit { is_mem_uninit: bool }, + } + + impl InitKind { + fn is_uninit(self) -> bool { + matches!(self, InitKind::Uninit { .. }) + } } /// Information about why a type cannot be initialized this way. @@ -2398,7 +2404,9 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { let def_id = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id()?; match cx.tcx.get_diagnostic_name(def_id) { Some(sym::mem_zeroed) => return Some(InitKind::Zeroed), - Some(sym::mem_uninitialized) => return Some(InitKind::Uninit), + Some(sym::mem_uninitialized) => { + return Some(InitKind::Uninit { is_mem_uninit: true }); + } Some(sym::transmute) if is_zero(&args[0]) => return Some(InitKind::Zeroed), _ => {} } @@ -2414,7 +2422,9 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { let def_id = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id()?; match cx.tcx.get_diagnostic_name(def_id) { Some(sym::maybe_uninit_zeroed) => return Some(InitKind::Zeroed), - Some(sym::maybe_uninit_uninit) => return Some(InitKind::Uninit), + Some(sym::maybe_uninit_uninit) => { + return Some(InitKind::Uninit { is_mem_uninit: false }); + } _ => {} } } @@ -2453,19 +2463,19 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { Some(("the vtable of a wide raw pointer must be non-null".to_string(), None)) } // Primitive types with other constraints. - Bool if init == InitKind::Uninit => { + Bool if init.is_uninit() => { Some(("booleans must be either `true` or `false`".to_string(), None)) } - Char if init == InitKind::Uninit => { + Char if init.is_uninit() => { Some(("characters must be a valid Unicode codepoint".to_string(), None)) } - Int(_) | Uint(_) if init == InitKind::Uninit => { + Int(_) | Uint(_) if init.is_uninit() => { Some(("integers must not be uninitialized".to_string(), None)) } - Float(_) if init == InitKind::Uninit => { + Float(_) if init.is_uninit() => { Some(("floats must not be uninitialized".to_string(), None)) } - RawPtr(_) if init == InitKind::Uninit => { + RawPtr(_) if init.is_uninit() => { Some(("raw pointers must not be uninitialized".to_string(), None)) } // Recurse and checks for some compound types. @@ -2479,9 +2489,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { (Bound::Included(lo), _) if lo > 0 => { return Some((format!("`{}` must be non-null", ty), None)); } - (Bound::Included(_), _) | (_, Bound::Included(_)) - if init == InitKind::Uninit => - { + (Bound::Included(_), _) | (_, Bound::Included(_)) if init.is_uninit() => { return Some(( format!( "`{}` must be initialized inside its custom valid range", @@ -2523,7 +2531,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { } // Multi-variant enum. _ => { - if init == InitKind::Uninit && is_multi_variant(*adt_def) { + if init.is_uninit() && is_multi_variant(*adt_def) { let span = cx.tcx.def_span(adt_def.did()); Some(( "enums have to be initialized to a variant".to_string(), @@ -2560,6 +2568,16 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { // using zeroed or uninitialized memory. // We are extremely conservative with what we warn about. let conjured_ty = cx.typeck_results().expr_ty(expr); + + if init == (InitKind::Uninit { is_mem_uninit: true }) { + // We don't want to warn here for things that mem_uninitialized will warn about + if with_no_trimmed_paths!( + crate::mem_uninitialized::ty_find_init_error(cx, conjured_ty).is_some() + ) { + return; + } + } + if let Some((msg, span)) = with_no_trimmed_paths!(ty_find_init_error(cx, conjured_ty, init)) { @@ -2570,7 +2588,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { conjured_ty, match init { InitKind::Zeroed => "zero-initialization", - InitKind::Uninit => "being left uninitialized", + InitKind::Uninit { .. } => "being left uninitialized", }, )); err.span_label(expr.span, "this code causes undefined behavior when executed"); @@ -2591,235 +2609,6 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { } } -declare_lint! { - /// The `mem_uninitialized` lint detects all uses of `std::mem::uninitialized` that are not - /// known to be safe. - /// - /// This function is extremely dangerous, and nearly all uses of it cause immediate Undefined - /// Behavior. - /// - /// ### Example - /// - /// ```rust,compile_fail - /// #![deny(mem_uninitialized)] - /// fn main() { - /// let x: [char; 16] = unsafe { std::mem::uninitialized() }; - /// } - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// Creating an invalid value is undefined behavior, and nearly all types are invalid when left - /// uninitialized. - /// - /// To avoid churn, however, this will not lint for types made up entirely of integers, floats, - /// or raw pointers. This is not saying that leaving these types uninitialized is okay, - /// however. - pub MEM_UNINITIALIZED, - Warn, - "use of mem::uninitialized", - @future_incompatible = FutureIncompatibleInfo { - reference: "FIXME: fill this in", - reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow, - explain_reason: false, - }; -} - -declare_lint_pass!(MemUninitialized => [MEM_UNINITIALIZED]); - -impl<'tcx> LateLintPass<'tcx> for MemUninitialized { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &hir::Expr<'_>) { - /// Information about why a type cannot be initialized this way. - /// Contains an error message and optionally a span to point at. - struct InitError { - msg: String, - span: Option, - generic: bool, - } - - impl InitError { - fn new(msg: impl Into) -> Self { - Self { msg: msg.into(), span: None, generic: false } - } - - fn with_span(msg: impl Into, span: Span) -> Self { - Self { msg: msg.into(), span: Some(span), generic: false } - } - - fn generic() -> Self { - Self { - msg: "type might not be allowed to be left uninitialized".to_string(), - span: None, - generic: true, - } - } - } - - /// Determine if this expression is a "dangerous initialization". - fn is_dangerous_init(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { - if let hir::ExprKind::Call(ref path_expr, _) = expr.kind { - // Find calls to `mem::{uninitialized,zeroed}` methods. - if let hir::ExprKind::Path(ref qpath) = path_expr.kind { - if let Some(def_id) = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id() { - if cx.tcx.is_diagnostic_item(sym::mem_uninitialized, def_id) { - return true; - } - } - } - } - - false - } - - /// Return `None` only if we are sure this type does - /// allow being left uninitialized. - fn ty_find_init_error<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option { - use rustc_type_ir::sty::TyKind::*; - match ty.kind() { - // Primitive types that don't like 0 as a value. - Ref(..) => Some(InitError::new("references must be non-null")), - Adt(..) if ty.is_box() => Some(InitError::new("`Box` must be non-null")), - FnPtr(..) => Some(InitError::new("function pointers must be non-null")), - Never => Some(InitError::new("the `!` type has no valid value")), - RawPtr(tm) if matches!(tm.ty.kind(), Dynamic(..)) => - // raw ptr to dyn Trait - { - Some(InitError::new("the vtable of a wide raw pointer must be non-null")) - } - // Primitive types with other constraints. - Bool => Some(InitError::new("booleans must be either `true` or `false`")), - Char => Some(InitError::new("characters must be a valid Unicode codepoint")), - Adt(adt_def, _) if adt_def.is_union() => None, - // Recurse and checks for some compound types. - Adt(adt_def, substs) => { - // First check if this ADT has a layout attribute (like `NonNull` and friends). - use std::ops::Bound; - match cx.tcx.layout_scalar_valid_range(adt_def.did()) { - // We exploit here that `layout_scalar_valid_range` will never - // return `Bound::Excluded`. (And we have tests checking that we - // handle the attribute correctly.) - (Bound::Included(lo), _) if lo > 0 => { - return Some(InitError::new(format!("`{ty}` must be non-null"))); - } - (Bound::Included(_), _) | (_, Bound::Included(_)) => { - return Some(InitError::new(format!( - "`{ty}` must be initialized inside its custom valid range" - ))); - } - _ => {} - } - // Now, recurse. - match adt_def.variants().len() { - 0 => Some(InitError::new("enums with no variants have no valid value")), - 1 => { - // Struct, or enum with exactly one variant. - // Proceed recursively, check all fields. - let variant = &adt_def.variant(VariantIdx::from_u32(0)); - variant.fields.iter().find_map(|field| { - ty_find_init_error(cx, field.ty(cx.tcx, substs)).map( - |InitError { mut msg, span, generic }| { - if span.is_none() { - // Point to this field, should be helpful for figuring - // out where the source of the error is. - let span = cx.tcx.def_span(field.did); - write!( - &mut msg, - " (in this {} field)", - adt_def.descr() - ) - .unwrap(); - - InitError { msg, span: Some(span), generic } - } else { - // Just forward. - InitError { msg, span, generic } - } - }, - ) - }) - } - // Multi-variant enum. - _ => { - // This will warn on something like Result, !> which - // is not UB under the current enum layout, even ignoring the 0x01 - // filling. - // - // That's probably fine though. - let span = cx.tcx.def_span(adt_def.did()); - Some(InitError::with_span( - "enums have to be initialized to a variant", - span, - )) - } - } - } - Tuple(..) => { - // Proceed recursively, check all fields. - ty.tuple_fields().iter().find_map(|field| ty_find_init_error(cx, field)) - } - Array(ty, len) => { - match len.try_eval_usize(cx.tcx, cx.param_env) { - // Array known to be zero sized, we can't warn. - Some(0) => None, - - // Array length known to be nonzero, warn. - Some(1..) => ty_find_init_error(cx, *ty), - - // Array length unknown, use the "might not permit" wording. - None => ty_find_init_error(cx, *ty).map(|mut e| { - e.generic = true; - e - }), - } - } - Int(_) | Uint(_) | Float(_) | RawPtr(_) => { - // These are Plain Old Data types that people expect to work if they leave them - // uninitialized. - None - } - // Pessimistic fallback. - _ => Some(InitError::generic()), - } - } - - if is_dangerous_init(cx, expr) { - // This conjures an instance of a type out of nothing, - // using zeroed or uninitialized memory. - // We are extremely conservative with what we warn about. - let conjured_ty = cx.typeck_results().expr_ty(expr); - if let Some(init_error) = with_no_trimmed_paths!(ty_find_init_error(cx, conjured_ty)) { - let main_msg = with_no_trimmed_paths!(if init_error.generic { - format!( - "the type `{conjured_ty}` is generic, and might not permit being left uninitialized" - ) - } else { - format!("the type `{conjured_ty}` does not permit being left uninitialized") - }); - - // FIXME(davidtwco): make translatable - cx.struct_span_lint(MEM_UNINITIALIZED, expr.span, |lint| { - let mut err = lint.build(&main_msg); - - err.span_label(expr.span, "this code causes undefined behavior when executed"); - err.span_label( - expr.span, - "help: use `MaybeUninit` instead, \ - and only call `assume_init` after initialization is done", - ); - if let Some(span) = init_error.span { - err.span_note(span, &init_error.msg); - } else { - err.note(&init_error.msg); - } - err.emit(); - }); - } - } - } -} - declare_lint! { /// The `clashing_extern_declarations` lint detects when an `extern fn` /// has been declared with the same name but different types. diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index b5cc970a4bd00..54ce067d54465 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -57,6 +57,7 @@ mod internal; mod late; mod let_underscore; mod levels; +mod mem_uninitialized; mod methods; mod non_ascii_idents; mod non_fmt_panic; @@ -69,6 +70,8 @@ mod traits; mod types; mod unused; +use mem_uninitialized::MemUninitialized; + pub use array_into_iter::ARRAY_INTO_ITER; use rustc_ast as ast; diff --git a/compiler/rustc_lint/src/mem_uninitialized.rs b/compiler/rustc_lint/src/mem_uninitialized.rs new file mode 100644 index 0000000000000..f14441d0ce73e --- /dev/null +++ b/compiler/rustc_lint/src/mem_uninitialized.rs @@ -0,0 +1,233 @@ +use crate::context::LintContext; +use crate::LateContext; +use crate::LateLintPass; +use rustc_hir as hir; +use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_middle::ty::Ty; +use rustc_session::lint::FutureIncompatibilityReason; +use rustc_span::symbol::sym; +use rustc_span::Span; +use rustc_target::abi::VariantIdx; +use std::fmt::Write; + +declare_lint! { + /// The `mem_uninitialized` lint detects all uses of `std::mem::uninitialized` that are not + /// known to be safe. + /// + /// This function is extremely dangerous, and nearly all uses of it cause immediate Undefined + /// Behavior. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// #![deny(mem_uninitialized)] + /// fn main() { + /// let x: [char; 16] = unsafe { std::mem::uninitialized() }; + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Creating an invalid value is undefined behavior, and nearly all types are invalid when left + /// uninitialized. + /// + /// To avoid churn, however, this will not lint for types made up entirely of integers, floats, + /// or raw pointers. This is not saying that leaving these types uninitialized is okay, + /// however. + pub MEM_UNINITIALIZED, + Warn, + "use of mem::uninitialized", + @future_incompatible = FutureIncompatibleInfo { + reference: "FIXME: fill this in", + reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow, + explain_reason: false, + }; +} + +declare_lint_pass!(MemUninitialized => [MEM_UNINITIALIZED]); + +/// Information about why a type cannot be initialized this way. +/// Contains an error message and optionally a span to point at. +pub struct InitError { + msg: String, + span: Option, + generic: bool, +} + +impl InitError { + fn new(msg: impl Into) -> Self { + Self { msg: msg.into(), span: None, generic: false } + } + + fn with_span(msg: impl Into, span: Span) -> Self { + Self { msg: msg.into(), span: Some(span), generic: false } + } + + fn generic() -> Self { + Self { + msg: "type might not be allowed to be left uninitialized".to_string(), + span: None, + generic: true, + } + } +} + +/// Return `None` only if we are sure this type does +/// allow being left uninitialized. +pub fn ty_find_init_error<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option { + use rustc_type_ir::sty::TyKind::*; + match ty.kind() { + // Primitive types that don't like 0 as a value. + Ref(..) => Some(InitError::new("references must be non-null")), + Adt(..) if ty.is_box() => Some(InitError::new("`Box` must be non-null")), + FnPtr(..) => Some(InitError::new("function pointers must be non-null")), + Never => Some(InitError::new("the `!` type has no valid value")), + RawPtr(tm) if matches!(tm.ty.kind(), Dynamic(..)) => + // raw ptr to dyn Trait + { + Some(InitError::new("the vtable of a wide raw pointer must be non-null")) + } + // Primitive types with other constraints. + Bool => Some(InitError::new("booleans must be either `true` or `false`")), + Char => Some(InitError::new("characters must be a valid Unicode codepoint")), + Adt(adt_def, _) if adt_def.is_union() => None, + // Recurse and checks for some compound types. + Adt(adt_def, substs) => { + // First check if this ADT has a layout attribute (like `NonNull` and friends). + use std::ops::Bound; + match cx.tcx.layout_scalar_valid_range(adt_def.did()) { + // We exploit here that `layout_scalar_valid_range` will never + // return `Bound::Excluded`. (And we have tests checking that we + // handle the attribute correctly.) + (Bound::Included(lo), _) if lo > 0 => { + return Some(InitError::new(format!("`{ty}` must be non-null"))); + } + (Bound::Included(_), _) | (_, Bound::Included(_)) => { + return Some(InitError::new(format!( + "`{ty}` must be initialized inside its custom valid range" + ))); + } + _ => {} + } + // Now, recurse. + match adt_def.variants().len() { + 0 => Some(InitError::new("enums with no variants have no valid value")), + 1 => { + // Struct, or enum with exactly one variant. + // Proceed recursively, check all fields. + let variant = &adt_def.variant(VariantIdx::from_u32(0)); + variant.fields.iter().find_map(|field| { + ty_find_init_error(cx, field.ty(cx.tcx, substs)).map( + |InitError { mut msg, span, generic }| { + if span.is_none() { + // Point to this field, should be helpful for figuring + // out where the source of the error is. + let span = cx.tcx.def_span(field.did); + write!(&mut msg, " (in this {} field)", adt_def.descr()) + .unwrap(); + + InitError { msg, span: Some(span), generic } + } else { + // Just forward. + InitError { msg, span, generic } + } + }, + ) + }) + } + // Multi-variant enum. + _ => { + // This will warn on something like Result, !> which + // is not UB under the current enum layout, even ignoring the 0x01 + // filling. + // + // That's probably fine though. + let span = cx.tcx.def_span(adt_def.did()); + Some(InitError::with_span("enums have to be initialized to a variant", span)) + } + } + } + Tuple(..) => { + // Proceed recursively, check all fields. + ty.tuple_fields().iter().find_map(|field| ty_find_init_error(cx, field)) + } + Array(ty, len) => { + match len.try_eval_usize(cx.tcx, cx.param_env) { + // Array known to be zero sized, we can't warn. + Some(0) => None, + + // Array length known to be nonzero, warn. + Some(1..) => ty_find_init_error(cx, *ty), + + // Array length unknown, use the "might not permit" wording. + None => ty_find_init_error(cx, *ty).map(|mut e| { + e.generic = true; + e + }), + } + } + Int(_) | Uint(_) | Float(_) | RawPtr(_) => { + // These are Plain Old Data types that people expect to work if they leave them + // uninitialized. + None + } + // Pessimistic fallback. + _ => Some(InitError::generic()), + } +} + +impl<'tcx> LateLintPass<'tcx> for MemUninitialized { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &hir::Expr<'_>) { + /// Determine if this expression is a "dangerous initialization". + fn is_dangerous_init(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { + if let hir::ExprKind::Call(ref path_expr, _) = expr.kind { + // Find calls to `mem::{uninitialized,zeroed}` methods. + if let hir::ExprKind::Path(ref qpath) = path_expr.kind { + if let Some(def_id) = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id() { + if cx.tcx.is_diagnostic_item(sym::mem_uninitialized, def_id) { + return true; + } + } + } + } + + false + } + + if is_dangerous_init(cx, expr) { + // This conjures an instance of a type out of nothing, + // using zeroed or uninitialized memory. + // We are extremely conservative with what we warn about. + let conjured_ty = cx.typeck_results().expr_ty(expr); + if let Some(init_error) = with_no_trimmed_paths!(ty_find_init_error(cx, conjured_ty)) { + let main_msg = with_no_trimmed_paths!(if init_error.generic { + format!( + "the type `{conjured_ty}` is generic, and might not permit being left uninitialized" + ) + } else { + format!("the type `{conjured_ty}` does not permit being left uninitialized") + }); + + // FIXME(davidtwco): make translatable + cx.struct_span_lint(MEM_UNINITIALIZED, expr.span, |lint| { + let mut err = lint.build(&main_msg); + + err.span_label(expr.span, "this code causes undefined behavior when executed"); + err.span_label( + expr.span, + "help: use `MaybeUninit` instead, \ + and only call `assume_init` after initialization is done", + ); + if let Some(span) = init_error.span { + err.span_note(span, &init_error.msg); + } else { + err.note(&init_error.msg); + } + err.emit(); + }); + } + } + } +} diff --git a/src/test/ui/lint/uninitialized-zeroed.rs b/src/test/ui/lint/uninitialized-zeroed.rs index a00c7881fb916..d4c3cbdb57fff 100644 --- a/src/test/ui/lint/uninitialized-zeroed.rs +++ b/src/test/ui/lint/uninitialized-zeroed.rs @@ -38,10 +38,10 @@ enum OneFruit { fn generic() { unsafe { let _val: &'static T = mem::zeroed(); //~ ERROR: does not permit zero-initialization - let _val: &'static T = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: &'static T = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized let _val: Wrap<&'static T> = mem::zeroed(); //~ ERROR: does not permit zero-initialization - let _val: Wrap<&'static T> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: Wrap<&'static T> = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized } } @@ -49,56 +49,56 @@ fn main() { unsafe { // Things that cannot even be zero. let _val: ! = mem::zeroed(); //~ ERROR: does not permit zero-initialization - let _val: ! = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: ! = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized let _val: (i32, !) = mem::zeroed(); //~ ERROR: does not permit zero-initialization - let _val: (i32, !) = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: (i32, !) = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized let _val: Void = mem::zeroed(); //~ ERROR: does not permit zero-initialization - let _val: Void = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: Void = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized let _val: &'static i32 = mem::zeroed(); //~ ERROR: does not permit zero-initialization - let _val: &'static i32 = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: &'static i32 = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized let _val: Ref = mem::zeroed(); //~ ERROR: does not permit zero-initialization - let _val: Ref = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: Ref = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized let _val: fn() = mem::zeroed(); //~ ERROR: does not permit zero-initialization - let _val: fn() = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: fn() = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized let _val: Wrap = mem::zeroed(); //~ ERROR: does not permit zero-initialization - let _val: Wrap = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: Wrap = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized let _val: WrapEnum = mem::zeroed(); //~ ERROR: does not permit zero-initialization - let _val: WrapEnum = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: WrapEnum = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized let _val: Wrap<(RefPair, i32)> = mem::zeroed(); //~ ERROR: does not permit zero-initialization - let _val: Wrap<(RefPair, i32)> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: Wrap<(RefPair, i32)> = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized let _val: NonNull = mem::zeroed(); //~ ERROR: does not permit zero-initialization - let _val: NonNull = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: NonNull = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized let _val: *const dyn Send = mem::zeroed(); //~ ERROR: does not permit zero-initialization - let _val: *const dyn Send = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: *const dyn Send = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized let _val: [fn(); 2] = mem::zeroed(); //~ ERROR: does not permit zero-initialization - let _val: [fn(); 2] = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: [fn(); 2] = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized // Things that can be zero, but not uninit. let _val: bool = mem::zeroed(); - let _val: bool = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: bool = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized let _val: Wrap = mem::zeroed(); - let _val: Wrap = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: Wrap = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized let _val: NonBig = mem::zeroed(); - let _val: NonBig = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: NonBig = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized let _val: Fruit = mem::zeroed(); - let _val: Fruit = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: Fruit = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized let _val: [bool; 2] = mem::zeroed(); - let _val: [bool; 2] = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: [bool; 2] = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized let _val: i32 = mem::zeroed(); let _val: i32 = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized @@ -132,6 +132,6 @@ fn main() { // Some things that happen to work due to rustc implementation details, // but are not guaranteed to keep working. - let _val: OneFruit = mem::uninitialized(); + let _val: OneFruit = MaybeUninit::uninit().assume_init(); } } diff --git a/src/test/ui/lint/uninitialized-zeroed.stderr b/src/test/ui/lint/uninitialized-zeroed.stderr index 0c79f2ac1cb76..b6bf46e14fe26 100644 --- a/src/test/ui/lint/uninitialized-zeroed.stderr +++ b/src/test/ui/lint/uninitialized-zeroed.stderr @@ -17,8 +17,8 @@ LL | #![deny(invalid_value)] error: the type `&T` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:41:32 | -LL | let _val: &'static T = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _val: &'static T = MaybeUninit::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done @@ -43,8 +43,8 @@ LL | struct Wrap { wrapped: T } error: the type `Wrap<&T>` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:44:38 | -LL | let _val: Wrap<&'static T> = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _val: Wrap<&'static T> = MaybeUninit::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done @@ -69,8 +69,8 @@ LL | let _val: ! = mem::zeroed(); error: the type `!` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:52:23 | -LL | let _val: ! = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _val: ! = MaybeUninit::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done @@ -91,8 +91,8 @@ LL | let _val: (i32, !) = mem::zeroed(); error: the type `(i32, !)` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:55:30 | -LL | let _val: (i32, !) = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _val: (i32, !) = MaybeUninit::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done @@ -113,8 +113,8 @@ LL | let _val: Void = mem::zeroed(); error: the type `Void` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:58:26 | -LL | let _val: Void = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _val: Void = MaybeUninit::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done @@ -135,8 +135,8 @@ LL | let _val: &'static i32 = mem::zeroed(); error: the type `&i32` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:61:34 | -LL | let _val: &'static i32 = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _val: &'static i32 = MaybeUninit::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done @@ -161,8 +161,8 @@ LL | struct Ref(&'static i32); error: the type `Ref` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:64:25 | -LL | let _val: Ref = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _val: Ref = MaybeUninit::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done @@ -187,8 +187,8 @@ LL | let _val: fn() = mem::zeroed(); error: the type `fn()` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:67:26 | -LL | let _val: fn() = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _val: fn() = MaybeUninit::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done @@ -213,8 +213,8 @@ LL | struct Wrap { wrapped: T } error: the type `Wrap` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:70:32 | -LL | let _val: Wrap = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _val: Wrap = MaybeUninit::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done @@ -243,8 +243,8 @@ LL | enum WrapEnum { Wrapped(T) } error: the type `WrapEnum` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:73:36 | -LL | let _val: WrapEnum = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _val: WrapEnum = MaybeUninit::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done @@ -273,8 +273,8 @@ LL | struct RefPair((&'static i32, i32)); error: the type `Wrap<(RefPair, i32)>` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:76:42 | -LL | let _val: Wrap<(RefPair, i32)> = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _val: Wrap<(RefPair, i32)> = MaybeUninit::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done @@ -299,8 +299,8 @@ LL | let _val: NonNull = mem::zeroed(); error: the type `NonNull` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:79:34 | -LL | let _val: NonNull = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _val: NonNull = MaybeUninit::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done @@ -321,8 +321,8 @@ LL | let _val: *const dyn Send = mem::zeroed(); error: the type `*const dyn Send` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:82:37 | -LL | let _val: *const dyn Send = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _val: *const dyn Send = MaybeUninit::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done @@ -343,8 +343,8 @@ LL | let _val: [fn(); 2] = mem::zeroed(); error: the type `[fn(); 2]` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:85:31 | -LL | let _val: [fn(); 2] = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _val: [fn(); 2] = MaybeUninit::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done @@ -354,8 +354,8 @@ LL | let _val: [fn(); 2] = mem::uninitialized(); error: the type `bool` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:89:26 | -LL | let _val: bool = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _val: bool = MaybeUninit::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done @@ -365,8 +365,8 @@ LL | let _val: bool = mem::uninitialized(); error: the type `Wrap` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:92:32 | -LL | let _val: Wrap = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _val: Wrap = MaybeUninit::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done @@ -380,8 +380,8 @@ LL | struct Wrap { wrapped: T } error: the type `NonBig` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:95:28 | -LL | let _val: NonBig = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _val: NonBig = MaybeUninit::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done @@ -391,8 +391,8 @@ LL | let _val: NonBig = mem::uninitialized(); error: the type `Fruit` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:98:27 | -LL | let _val: Fruit = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _val: Fruit = MaybeUninit::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done @@ -406,8 +406,8 @@ LL | enum Fruit { error: the type `[bool; 2]` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:101:31 | -LL | let _val: [bool; 2] = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ +LL | let _val: [bool; 2] = MaybeUninit::uninit().assume_init(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done @@ -526,395 +526,3 @@ LL | let _val: bool = MaybeUninit::uninit().assume_init(); error: aborting due to 43 previous errors -Future incompatibility report: Future breakage diagnostic: -warning: the type `&T` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:41:32 - | -LL | let _val: &'static T = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in - = note: references must be non-null - -Future breakage diagnostic: -warning: the type `Wrap<&T>` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:44:38 - | -LL | let _val: Wrap<&'static T> = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in -note: references must be non-null (in this struct field) - --> $DIR/uninitialized-zeroed.rs:17:18 - | -LL | struct Wrap { wrapped: T } - | ^^^^^^^^^^ - -Future breakage diagnostic: -warning: the type `!` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:52:23 - | -LL | let _val: ! = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in - = note: the `!` type has no valid value - -Future breakage diagnostic: -warning: the type `(i32, !)` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:55:30 - | -LL | let _val: (i32, !) = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in - = note: the `!` type has no valid value - -Future breakage diagnostic: -warning: the type `Void` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:58:26 - | -LL | let _val: Void = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in - = note: enums with no variants have no valid value - -Future breakage diagnostic: -warning: the type `&i32` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:61:34 - | -LL | let _val: &'static i32 = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in - = note: references must be non-null - -Future breakage diagnostic: -warning: the type `Ref` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:64:25 - | -LL | let _val: Ref = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in -note: references must be non-null (in this struct field) - --> $DIR/uninitialized-zeroed.rs:14:12 - | -LL | struct Ref(&'static i32); - | ^^^^^^^^^^^^ - -Future breakage diagnostic: -warning: the type `fn()` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:67:26 - | -LL | let _val: fn() = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in - = note: function pointers must be non-null - -Future breakage diagnostic: -warning: the type `Wrap` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:70:32 - | -LL | let _val: Wrap = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in -note: function pointers must be non-null (in this struct field) - --> $DIR/uninitialized-zeroed.rs:17:18 - | -LL | struct Wrap { wrapped: T } - | ^^^^^^^^^^ - -Future breakage diagnostic: -warning: the type `WrapEnum` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:73:36 - | -LL | let _val: WrapEnum = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in -note: function pointers must be non-null (in this enum field) - --> $DIR/uninitialized-zeroed.rs:18:28 - | -LL | enum WrapEnum { Wrapped(T) } - | ^ - -Future breakage diagnostic: -warning: the type `Wrap<(RefPair, i32)>` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:76:42 - | -LL | let _val: Wrap<(RefPair, i32)> = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in -note: references must be non-null (in this struct field) - --> $DIR/uninitialized-zeroed.rs:15:16 - | -LL | struct RefPair((&'static i32, i32)); - | ^^^^^^^^^^^^^^^^^^^ - -Future breakage diagnostic: -warning: the type `std::ptr::NonNull` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:79:34 - | -LL | let _val: NonNull = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in - = note: `std::ptr::NonNull` must be non-null - -Future breakage diagnostic: -warning: the type `*const dyn std::marker::Send` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:82:37 - | -LL | let _val: *const dyn Send = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in - = note: the vtable of a wide raw pointer must be non-null - -Future breakage diagnostic: -warning: the type `[fn(); 2]` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:85:31 - | -LL | let _val: [fn(); 2] = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in - = note: function pointers must be non-null - -Future breakage diagnostic: -warning: the type `bool` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:89:26 - | -LL | let _val: bool = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in - = note: booleans must be either `true` or `false` - -Future breakage diagnostic: -warning: the type `Wrap` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:92:32 - | -LL | let _val: Wrap = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in -note: characters must be a valid Unicode codepoint (in this struct field) - --> $DIR/uninitialized-zeroed.rs:17:18 - | -LL | struct Wrap { wrapped: T } - | ^^^^^^^^^^ - -Future breakage diagnostic: -warning: the type `NonBig` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:95:28 - | -LL | let _val: NonBig = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in - = note: `NonBig` must be initialized inside its custom valid range - -Future breakage diagnostic: -warning: the type `Fruit` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:98:27 - | -LL | let _val: Fruit = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in -note: enums have to be initialized to a variant - --> $DIR/uninitialized-zeroed.rs:26:1 - | -LL | enum Fruit { - | ^^^^^^^^^^ - -Future breakage diagnostic: -warning: the type `[bool; 2]` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:101:31 - | -LL | let _val: [bool; 2] = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in - = note: booleans must be either `true` or `false` - -Future breakage diagnostic: -warning: the type `OneFruit` does not permit being left uninitialized - --> $DIR/uninitialized-zeroed.rs:124:30 - | -LL | let _val: OneFruit = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done - | -note: the lint level is defined here - --> $DIR/uninitialized-zeroed.rs:5:22 - | -LL | #![allow(deprecated, mem_uninitialized)] - | ^^^^^^^^^^^^^^^^^ - = note: for more information, see FIXME: fill this in -note: enums have to be initialized to a variant - --> $DIR/uninitialized-zeroed.rs:32:1 - | -LL | enum OneFruit { - | ^^^^^^^^^^^^^ -