1
Fork 0

Rollup merge of #102281 - RalfJung:invalid-enums, r=cjgillot

make invalid_value lint a bit smarter around enums

Fixes https://github.com/rust-lang/rust/issues/102043
This commit is contained in:
Matthias Krüger 2022-09-27 21:42:22 +02:00 committed by GitHub
commit 8d2faa2ae8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 343 additions and 163 deletions

View file

@ -46,8 +46,7 @@ use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::layout::{LayoutError, LayoutOf}; use rustc_middle::ty::layout::{LayoutError, LayoutOf};
use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::Instance; use rustc_middle::ty::{self, Instance, Ty, TyCtxt, VariantDef};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_session::lint::{BuiltinLintDiagnostics, FutureIncompatibilityReason}; use rustc_session::lint::{BuiltinLintDiagnostics, FutureIncompatibilityReason};
use rustc_span::edition::Edition; use rustc_span::edition::Edition;
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
@ -2425,12 +2424,63 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
None None
} }
/// Test if this enum has several actually "existing" variants. /// Determines whether the given type is inhabited. `None` means that we don't know.
/// Zero-sized uninhabited variants do not always have a tag assigned and thus do not "exist". fn ty_inhabited<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<bool> {
fn is_multi_variant<'tcx>(adt: ty::AdtDef<'tcx>) -> bool { use rustc_type_ir::sty::TyKind::*;
// As an approximation, we only count dataless variants. Those are definitely inhabited. if !cx.tcx.type_uninhabited_from(cx.param_env.and(ty)).is_empty() {
let existing_variants = adt.variants().iter().filter(|v| v.fields.is_empty()).count(); // This is definitely uninhabited from some module.
existing_variants > 1 return Some(false);
}
match ty.kind() {
Never => Some(false),
Int(_) | Uint(_) | Float(_) | Bool | Char | RawPtr(_) => Some(true),
// Fallback for more complicated types. (Note that `&!` might be considered
// uninhabited so references are "complicated", too.)
_ => None,
}
}
/// Determines whether a product type formed from a list of types is inhabited.
fn tys_inhabited<'tcx>(
cx: &LateContext<'tcx>,
tys: impl Iterator<Item = Ty<'tcx>>,
) -> Option<bool> {
let mut definitely_inhabited = true; // with no fields, we are definitely inhabited.
for ty in tys {
match ty_inhabited(cx, ty) {
// If any type is uninhabited, the product is uninhabited.
Some(false) => return Some(false),
// Otherwise go searching for a `None`.
None => {
// We don't know.
definitely_inhabited = false;
}
Some(true) => {}
}
}
if definitely_inhabited { Some(true) } else { None }
}
fn variant_find_init_error<'tcx>(
cx: &LateContext<'tcx>,
variant: &VariantDef,
substs: ty::SubstsRef<'tcx>,
descr: &str,
init: InitKind,
) -> Option<InitError> {
variant.fields.iter().find_map(|field| {
ty_find_init_error(cx, field.ty(cx.tcx, substs), init).map(|(mut msg, span)| {
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 {descr})").unwrap();
(msg, Some(span))
} else {
// Just forward.
(msg, span)
}
})
})
} }
/// Return `Some` only if we are sure this type does *not* /// Return `Some` only if we are sure this type does *not*
@ -2468,7 +2518,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
RawPtr(_) if init == InitKind::Uninit => { RawPtr(_) if init == InitKind::Uninit => {
Some(("raw pointers must not be uninitialized".to_string(), None)) Some(("raw pointers must not be uninitialized".to_string(), None))
} }
// Recurse and checks for some compound types. // Recurse and checks for some compound types. (but not unions)
Adt(adt_def, substs) if !adt_def.is_union() => { Adt(adt_def, substs) if !adt_def.is_union() => {
// First check if this ADT has a layout attribute (like `NonNull` and friends). // First check if this ADT has a layout attribute (like `NonNull` and friends).
use std::ops::Bound; use std::ops::Bound;
@ -2476,6 +2526,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
// We exploit here that `layout_scalar_valid_range` will never // We exploit here that `layout_scalar_valid_range` will never
// return `Bound::Excluded`. (And we have tests checking that we // return `Bound::Excluded`. (And we have tests checking that we
// handle the attribute correctly.) // handle the attribute correctly.)
// We don't add a span since users cannot declare such types anyway.
(Bound::Included(lo), _) if lo > 0 => { (Bound::Included(lo), _) if lo > 0 => {
return Some((format!("`{}` must be non-null", ty), None)); return Some((format!("`{}` must be non-null", ty), None));
} }
@ -2492,50 +2543,65 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
} }
_ => {} _ => {}
} }
// Now, recurse. // Handle structs.
match adt_def.variants().len() { if adt_def.is_struct() {
0 => Some(("enums with no variants have no valid value".to_string(), None)), return variant_find_init_error(
1 => { cx,
// Struct, or enum with exactly one variant. adt_def.non_enum_variant(),
// Proceed recursively, check all fields. substs,
let variant = &adt_def.variant(VariantIdx::from_u32(0)); "struct field",
variant.fields.iter().find_map(|field| { init,
ty_find_init_error(cx, field.ty(cx.tcx, substs), init).map( );
|(mut msg, span)| { }
if span.is_none() { // And now, enums.
// Point to this field, should be helpful for figuring let span = cx.tcx.def_span(adt_def.did());
// out where the source of the error is. let mut potential_variants = adt_def.variants().iter().filter_map(|variant| {
let span = cx.tcx.def_span(field.did); let inhabited = tys_inhabited(
write!( cx,
&mut msg, variant.fields.iter().map(|field| field.ty(cx.tcx, substs)),
" (in this {} field)", );
adt_def.descr() let definitely_inhabited = match inhabited {
) // Entirely skip uninhbaited variants.
.unwrap(); Some(false) => return None,
(msg, Some(span)) // Forward the others, but remember which ones are definitely inhabited.
} else { Some(true) => true,
// Just forward. None => false,
(msg, span) };
} Some((variant, definitely_inhabited))
}, });
) let Some(first_variant) = potential_variants.next() else {
}) return Some(("enums with no inhabited variants have no valid value".to_string(), Some(span)));
} };
// Multi-variant enum. // So we have at least one potentially inhabited variant. Might we have two?
_ => { let Some(second_variant) = potential_variants.next() else {
if init == InitKind::Uninit && is_multi_variant(*adt_def) { // There is only one potentially inhabited variant. So we can recursively check that variant!
let span = cx.tcx.def_span(adt_def.did()); return variant_find_init_error(
Some(( cx,
"enums have to be initialized to a variant".to_string(), &first_variant.0,
Some(span), substs,
)) "field of the only potentially inhabited enum variant",
} else { init,
// In principle, for zero-initialization we could figure out which variant corresponds );
// to tag 0, and check that... but for now we just accept all zero-initializations. };
None // So we have at least two potentially inhabited variants.
} // If we can prove that we have at least two *definitely* inhabited variants,
// then we have a tag and hence leaving this uninit is definitely disallowed.
// (Leaving it zeroed could be okay, depending on which variant is encoded as zero tag.)
if init == InitKind::Uninit {
let definitely_inhabited = (first_variant.1 as usize)
+ (second_variant.1 as usize)
+ potential_variants
.filter(|(_variant, definitely_inhabited)| *definitely_inhabited)
.count();
if definitely_inhabited > 1 {
return Some((
"enums with multiple inhabited variants have to be initialized to a variant".to_string(),
Some(span),
));
} }
} }
// We couldn't find anything wrong here.
None
} }
Tuple(..) => { Tuple(..) => {
// Proceed recursively, check all fields. // Proceed recursively, check all fields.

View file

@ -1,5 +1,5 @@
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:23:1 --> $DIR/ub-enum.rs:24:1
| |
LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) }; LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) };
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered 0x00000001, but expected a valid enum tag | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered 0x00000001, but expected a valid enum tag
@ -10,7 +10,7 @@ LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) };
} }
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:26:1 --> $DIR/ub-enum.rs:27:1
| |
LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) }; LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
| ^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -22,7 +22,7 @@ LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:30:1 --> $DIR/ub-enum.rs:31:1
| |
LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) }; LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -33,7 +33,7 @@ LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:43:1 --> $DIR/ub-enum.rs:44:1
| |
LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) }; LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) };
| ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered 0x00000000, but expected a valid enum tag | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered 0x00000000, but expected a valid enum tag
@ -44,7 +44,7 @@ LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) };
} }
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:45:1 --> $DIR/ub-enum.rs:46:1
| |
LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) }; LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -55,7 +55,7 @@ LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:49:1 --> $DIR/ub-enum.rs:50:1
| |
LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) }; LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -66,13 +66,13 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/ub-enum.rs:59:42 --> $DIR/ub-enum.rs:60:42
| |
LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init }; LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:64:1 --> $DIR/ub-enum.rs:65:1
| |
LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) }; LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -83,7 +83,7 @@ LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:82:1 --> $DIR/ub-enum.rs:83:1
| |
LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) }; LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(B)>.0: encountered a value of the never type `!` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(B)>.0: encountered a value of the never type `!`
@ -94,7 +94,7 @@ LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:84:1 --> $DIR/ub-enum.rs:85:1
| |
LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) }; LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(D)>.0: encountered a value of uninhabited type Never | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(D)>.0: encountered a value of uninhabited type Never
@ -105,7 +105,7 @@ LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:92:1 --> $DIR/ub-enum.rs:93:1
| |
LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) })); LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
@ -116,13 +116,13 @@ LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::tran
} }
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/ub-enum.rs:97:77 --> $DIR/ub-enum.rs:98:77
| |
LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) }; LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) };
| ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/ub-enum.rs:99:77 --> $DIR/ub-enum.rs:100:77
| |
LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) }; LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) };
| ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
@ -132,7 +132,7 @@ error: aborting due to 13 previous errors
For more information about this error, try `rustc --explain E0080`. For more information about this error, try `rustc --explain E0080`.
Future incompatibility report: Future breakage diagnostic: Future incompatibility report: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:26:1 --> $DIR/ub-enum.rs:27:1
| |
LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) }; LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
| ^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -145,7 +145,7 @@ LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:30:1 --> $DIR/ub-enum.rs:31:1
| |
LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) }; LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -158,7 +158,7 @@ LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:45:1 --> $DIR/ub-enum.rs:46:1
| |
LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) }; LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -171,7 +171,7 @@ LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:49:1 --> $DIR/ub-enum.rs:50:1
| |
LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) }; LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -184,7 +184,7 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:64:1 --> $DIR/ub-enum.rs:65:1
| |
LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) }; LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes

View file

@ -1,5 +1,5 @@
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:23:1 --> $DIR/ub-enum.rs:24:1
| |
LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) }; LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) };
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered 0x0000000000000001, but expected a valid enum tag | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered 0x0000000000000001, but expected a valid enum tag
@ -10,7 +10,7 @@ LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) };
} }
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:26:1 --> $DIR/ub-enum.rs:27:1
| |
LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) }; LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
| ^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -22,7 +22,7 @@ LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:30:1 --> $DIR/ub-enum.rs:31:1
| |
LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) }; LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -33,7 +33,7 @@ LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:43:1 --> $DIR/ub-enum.rs:44:1
| |
LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) }; LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) };
| ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered 0x0000000000000000, but expected a valid enum tag | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered 0x0000000000000000, but expected a valid enum tag
@ -44,7 +44,7 @@ LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) };
} }
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:45:1 --> $DIR/ub-enum.rs:46:1
| |
LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) }; LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -55,7 +55,7 @@ LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:49:1 --> $DIR/ub-enum.rs:50:1
| |
LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) }; LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -66,13 +66,13 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/ub-enum.rs:59:42 --> $DIR/ub-enum.rs:60:42
| |
LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init }; LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:64:1 --> $DIR/ub-enum.rs:65:1
| |
LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) }; LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -83,7 +83,7 @@ LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:82:1 --> $DIR/ub-enum.rs:83:1
| |
LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) }; LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(B)>.0: encountered a value of the never type `!` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(B)>.0: encountered a value of the never type `!`
@ -94,7 +94,7 @@ LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:84:1 --> $DIR/ub-enum.rs:85:1
| |
LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) }; LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(D)>.0: encountered a value of uninhabited type Never | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(D)>.0: encountered a value of uninhabited type Never
@ -105,7 +105,7 @@ LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute
} }
error[E0080]: it is undefined behavior to use this value error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:92:1 --> $DIR/ub-enum.rs:93:1
| |
LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) })); LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
@ -116,13 +116,13 @@ LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::tran
} }
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/ub-enum.rs:97:77 --> $DIR/ub-enum.rs:98:77
| |
LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) }; LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) };
| ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/ub-enum.rs:99:77 --> $DIR/ub-enum.rs:100:77
| |
LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) }; LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) };
| ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
@ -132,7 +132,7 @@ error: aborting due to 13 previous errors
For more information about this error, try `rustc --explain E0080`. For more information about this error, try `rustc --explain E0080`.
Future incompatibility report: Future breakage diagnostic: Future incompatibility report: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:26:1 --> $DIR/ub-enum.rs:27:1
| |
LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) }; LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
| ^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -145,7 +145,7 @@ LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:30:1 --> $DIR/ub-enum.rs:31:1
| |
LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) }; LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -158,7 +158,7 @@ LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:45:1 --> $DIR/ub-enum.rs:46:1
| |
LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) }; LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -171,7 +171,7 @@ LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:49:1 --> $DIR/ub-enum.rs:50:1
| |
LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) }; LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -184,7 +184,7 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
Future breakage diagnostic: Future breakage diagnostic:
error: any use of this value will cause an error error: any use of this value will cause an error
--> $DIR/ub-enum.rs:64:1 --> $DIR/ub-enum.rs:65:1
| |
LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) }; LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes

View file

@ -1,5 +1,6 @@
// stderr-per-bitwidth // stderr-per-bitwidth
#![feature(never_type)] #![feature(never_type)]
#![allow(invalid_value)]
use std::mem; use std::mem;

View file

@ -40,11 +40,11 @@ LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
| this code causes undefined behavior when executed | this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
note: enums with no variants have no valid value (in this struct field) note: enums with no inhabited variants have no valid value
--> $DIR/validate_uninhabited_zsts.rs:16:22 --> $DIR/validate_uninhabited_zsts.rs:13:5
| |
LL | pub struct Empty(Void); LL | enum Void {}
| ^^^^ | ^^^^^^^^^
error: aborting due to 2 previous errors; 2 warnings emitted error: aborting due to 2 previous errors; 2 warnings emitted

View file

@ -40,11 +40,11 @@ LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
| this code causes undefined behavior when executed | this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
note: enums with no variants have no valid value (in this struct field) note: enums with no inhabited variants have no valid value
--> $DIR/validate_uninhabited_zsts.rs:16:22 --> $DIR/validate_uninhabited_zsts.rs:13:5
| |
LL | pub struct Empty(Void); LL | enum Void {}
| ^^^^ | ^^^^^^^^^
error: aborting due to 2 previous errors; 2 warnings emitted error: aborting due to 2 previous errors; 2 warnings emitted

View file

@ -34,6 +34,16 @@ enum OneFruit {
Banana, Banana,
} }
enum OneFruitNonZero {
Apple(!),
Banana(NonZeroU32),
}
enum TwoUninhabited {
A(!),
B(Void),
}
#[allow(unused)] #[allow(unused)]
fn generic<T: 'static>() { fn generic<T: 'static>() {
unsafe { unsafe {
@ -84,6 +94,12 @@ fn main() {
let _val: [fn(); 2] = mem::zeroed(); //~ ERROR: does not permit zero-initialization 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] = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
let _val: TwoUninhabited = mem::zeroed(); //~ ERROR: does not permit zero-initialization
let _val: TwoUninhabited = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
let _val: OneFruitNonZero = mem::zeroed(); //~ ERROR: does not permit zero-initialization
let _val: OneFruitNonZero = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
// Things that can be zero, but not uninit. // Things that can be zero, but not uninit.
let _val: bool = mem::zeroed(); let _val: bool = mem::zeroed();
let _val: bool = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized let _val: bool = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
@ -112,6 +128,16 @@ fn main() {
let _val: *const [()] = mem::zeroed(); let _val: *const [()] = mem::zeroed();
let _val: *const [()] = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized let _val: *const [()] = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
// Things where 0 is okay due to rustc implementation details,
// but that are not guaranteed to keep working.
let _val: Result<i32, i32> = mem::zeroed();
let _val: Result<i32, i32> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
// Some things that happen to work due to rustc implementation details,
// but are not guaranteed to keep working.
let _val: OneFruit = mem::zeroed();
let _val: OneFruit = mem::uninitialized();
// Transmute-from-0 // Transmute-from-0
let _val: &'static i32 = mem::transmute(0usize); //~ ERROR: does not permit zero-initialization let _val: &'static i32 = mem::transmute(0usize); //~ ERROR: does not permit zero-initialization
let _val: &'static [i32] = mem::transmute((0usize, 0usize)); //~ ERROR: does not permit zero-initialization let _val: &'static [i32] = mem::transmute((0usize, 0usize)); //~ ERROR: does not permit zero-initialization
@ -129,9 +155,5 @@ fn main() {
let _val: bool = MaybeUninit::zeroed().assume_init(); let _val: bool = MaybeUninit::zeroed().assume_init();
let _val: [bool; 0] = MaybeUninit::uninit().assume_init(); let _val: [bool; 0] = MaybeUninit::uninit().assume_init();
let _val: [!; 0] = MaybeUninit::zeroed().assume_init(); let _val: [!; 0] = MaybeUninit::zeroed().assume_init();
// Some things that happen to work due to rustc implementation details,
// but are not guaranteed to keep working.
let _val: OneFruit = mem::uninitialized();
} }
} }

View file

@ -1,5 +1,5 @@
error: the type `&T` does not permit zero-initialization error: the type `&T` does not permit zero-initialization
--> $DIR/uninitialized-zeroed.rs:40:32 --> $DIR/invalid_value.rs:50:32
| |
LL | let _val: &'static T = mem::zeroed(); LL | let _val: &'static T = mem::zeroed();
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -8,14 +8,14 @@ LL | let _val: &'static T = mem::zeroed();
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/uninitialized-zeroed.rs:6:9 --> $DIR/invalid_value.rs:6:9
| |
LL | #![deny(invalid_value)] LL | #![deny(invalid_value)]
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
= note: references must be non-null = note: references must be non-null
error: the type `&T` does not permit being left uninitialized error: the type `&T` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:41:32 --> $DIR/invalid_value.rs:51:32
| |
LL | let _val: &'static T = mem::uninitialized(); LL | let _val: &'static T = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -26,7 +26,7 @@ LL | let _val: &'static T = mem::uninitialized();
= note: references must be non-null = note: references must be non-null
error: the type `Wrap<&T>` does not permit zero-initialization error: the type `Wrap<&T>` does not permit zero-initialization
--> $DIR/uninitialized-zeroed.rs:43:38 --> $DIR/invalid_value.rs:53:38
| |
LL | let _val: Wrap<&'static T> = mem::zeroed(); LL | let _val: Wrap<&'static T> = mem::zeroed();
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -35,13 +35,13 @@ LL | let _val: Wrap<&'static T> = mem::zeroed();
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
note: references must be non-null (in this struct field) note: references must be non-null (in this struct field)
--> $DIR/uninitialized-zeroed.rs:17:18 --> $DIR/invalid_value.rs:17:18
| |
LL | struct Wrap<T> { wrapped: T } LL | struct Wrap<T> { wrapped: T }
| ^^^^^^^^^^ | ^^^^^^^^^^
error: the type `Wrap<&T>` does not permit being left uninitialized error: the type `Wrap<&T>` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:44:38 --> $DIR/invalid_value.rs:54:38
| |
LL | let _val: Wrap<&'static T> = mem::uninitialized(); LL | let _val: Wrap<&'static T> = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -50,13 +50,13 @@ LL | let _val: Wrap<&'static T> = mem::uninitialized();
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
note: references must be non-null (in this struct field) note: references must be non-null (in this struct field)
--> $DIR/uninitialized-zeroed.rs:17:18 --> $DIR/invalid_value.rs:17:18
| |
LL | struct Wrap<T> { wrapped: T } LL | struct Wrap<T> { wrapped: T }
| ^^^^^^^^^^ | ^^^^^^^^^^
error: the type `!` does not permit zero-initialization error: the type `!` does not permit zero-initialization
--> $DIR/uninitialized-zeroed.rs:51:23 --> $DIR/invalid_value.rs:61:23
| |
LL | let _val: ! = mem::zeroed(); LL | let _val: ! = mem::zeroed();
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -67,7 +67,7 @@ LL | let _val: ! = mem::zeroed();
= note: the `!` type has no valid value = note: the `!` type has no valid value
error: the type `!` does not permit being left uninitialized error: the type `!` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:52:23 --> $DIR/invalid_value.rs:62:23
| |
LL | let _val: ! = mem::uninitialized(); LL | let _val: ! = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -78,7 +78,7 @@ LL | let _val: ! = mem::uninitialized();
= note: the `!` type has no valid value = note: the `!` type has no valid value
error: the type `(i32, !)` does not permit zero-initialization error: the type `(i32, !)` does not permit zero-initialization
--> $DIR/uninitialized-zeroed.rs:54:30 --> $DIR/invalid_value.rs:64:30
| |
LL | let _val: (i32, !) = mem::zeroed(); LL | let _val: (i32, !) = mem::zeroed();
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -89,7 +89,7 @@ LL | let _val: (i32, !) = mem::zeroed();
= note: the `!` type has no valid value = note: the `!` type has no valid value
error: the type `(i32, !)` does not permit being left uninitialized error: the type `(i32, !)` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:55:30 --> $DIR/invalid_value.rs:65:30
| |
LL | let _val: (i32, !) = mem::uninitialized(); LL | let _val: (i32, !) = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -100,7 +100,7 @@ LL | let _val: (i32, !) = mem::uninitialized();
= note: integers must not be uninitialized = note: integers must not be uninitialized
error: the type `Void` does not permit zero-initialization error: the type `Void` does not permit zero-initialization
--> $DIR/uninitialized-zeroed.rs:57:26 --> $DIR/invalid_value.rs:67:26
| |
LL | let _val: Void = mem::zeroed(); LL | let _val: Void = mem::zeroed();
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -108,10 +108,14 @@ LL | let _val: Void = mem::zeroed();
| this code causes undefined behavior when executed | this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
= note: enums with no variants have no valid value note: enums with no inhabited variants have no valid value
--> $DIR/invalid_value.rs:12:1
|
LL | enum Void {}
| ^^^^^^^^^
error: the type `Void` does not permit being left uninitialized error: the type `Void` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:58:26 --> $DIR/invalid_value.rs:68:26
| |
LL | let _val: Void = mem::uninitialized(); LL | let _val: Void = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -119,10 +123,14 @@ LL | let _val: Void = mem::uninitialized();
| this code causes undefined behavior when executed | this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
= note: enums with no variants have no valid value note: enums with no inhabited variants have no valid value
--> $DIR/invalid_value.rs:12:1
|
LL | enum Void {}
| ^^^^^^^^^
error: the type `&i32` does not permit zero-initialization error: the type `&i32` does not permit zero-initialization
--> $DIR/uninitialized-zeroed.rs:60:34 --> $DIR/invalid_value.rs:70:34
| |
LL | let _val: &'static i32 = mem::zeroed(); LL | let _val: &'static i32 = mem::zeroed();
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -133,7 +141,7 @@ LL | let _val: &'static i32 = mem::zeroed();
= note: references must be non-null = note: references must be non-null
error: the type `&i32` does not permit being left uninitialized error: the type `&i32` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:61:34 --> $DIR/invalid_value.rs:71:34
| |
LL | let _val: &'static i32 = mem::uninitialized(); LL | let _val: &'static i32 = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -144,7 +152,7 @@ LL | let _val: &'static i32 = mem::uninitialized();
= note: references must be non-null = note: references must be non-null
error: the type `Ref` does not permit zero-initialization error: the type `Ref` does not permit zero-initialization
--> $DIR/uninitialized-zeroed.rs:63:25 --> $DIR/invalid_value.rs:73:25
| |
LL | let _val: Ref = mem::zeroed(); LL | let _val: Ref = mem::zeroed();
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -153,13 +161,13 @@ LL | let _val: Ref = mem::zeroed();
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
note: references must be non-null (in this struct field) note: references must be non-null (in this struct field)
--> $DIR/uninitialized-zeroed.rs:14:12 --> $DIR/invalid_value.rs:14:12
| |
LL | struct Ref(&'static i32); LL | struct Ref(&'static i32);
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error: the type `Ref` does not permit being left uninitialized error: the type `Ref` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:64:25 --> $DIR/invalid_value.rs:74:25
| |
LL | let _val: Ref = mem::uninitialized(); LL | let _val: Ref = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -168,13 +176,13 @@ LL | let _val: Ref = mem::uninitialized();
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
note: references must be non-null (in this struct field) note: references must be non-null (in this struct field)
--> $DIR/uninitialized-zeroed.rs:14:12 --> $DIR/invalid_value.rs:14:12
| |
LL | struct Ref(&'static i32); LL | struct Ref(&'static i32);
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error: the type `fn()` does not permit zero-initialization error: the type `fn()` does not permit zero-initialization
--> $DIR/uninitialized-zeroed.rs:66:26 --> $DIR/invalid_value.rs:76:26
| |
LL | let _val: fn() = mem::zeroed(); LL | let _val: fn() = mem::zeroed();
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -185,7 +193,7 @@ LL | let _val: fn() = mem::zeroed();
= note: function pointers must be non-null = note: function pointers must be non-null
error: the type `fn()` does not permit being left uninitialized error: the type `fn()` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:67:26 --> $DIR/invalid_value.rs:77:26
| |
LL | let _val: fn() = mem::uninitialized(); LL | let _val: fn() = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -196,7 +204,7 @@ LL | let _val: fn() = mem::uninitialized();
= note: function pointers must be non-null = note: function pointers must be non-null
error: the type `Wrap<fn()>` does not permit zero-initialization error: the type `Wrap<fn()>` does not permit zero-initialization
--> $DIR/uninitialized-zeroed.rs:69:32 --> $DIR/invalid_value.rs:79:32
| |
LL | let _val: Wrap<fn()> = mem::zeroed(); LL | let _val: Wrap<fn()> = mem::zeroed();
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -205,13 +213,13 @@ LL | let _val: Wrap<fn()> = mem::zeroed();
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
note: function pointers must be non-null (in this struct field) note: function pointers must be non-null (in this struct field)
--> $DIR/uninitialized-zeroed.rs:17:18 --> $DIR/invalid_value.rs:17:18
| |
LL | struct Wrap<T> { wrapped: T } LL | struct Wrap<T> { wrapped: T }
| ^^^^^^^^^^ | ^^^^^^^^^^
error: the type `Wrap<fn()>` does not permit being left uninitialized error: the type `Wrap<fn()>` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:70:32 --> $DIR/invalid_value.rs:80:32
| |
LL | let _val: Wrap<fn()> = mem::uninitialized(); LL | let _val: Wrap<fn()> = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -220,13 +228,13 @@ LL | let _val: Wrap<fn()> = mem::uninitialized();
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
note: function pointers must be non-null (in this struct field) note: function pointers must be non-null (in this struct field)
--> $DIR/uninitialized-zeroed.rs:17:18 --> $DIR/invalid_value.rs:17:18
| |
LL | struct Wrap<T> { wrapped: T } LL | struct Wrap<T> { wrapped: T }
| ^^^^^^^^^^ | ^^^^^^^^^^
error: the type `WrapEnum<fn()>` does not permit zero-initialization error: the type `WrapEnum<fn()>` does not permit zero-initialization
--> $DIR/uninitialized-zeroed.rs:72:36 --> $DIR/invalid_value.rs:82:36
| |
LL | let _val: WrapEnum<fn()> = mem::zeroed(); LL | let _val: WrapEnum<fn()> = mem::zeroed();
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -234,14 +242,14 @@ LL | let _val: WrapEnum<fn()> = mem::zeroed();
| this code causes undefined behavior when executed | this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
note: function pointers must be non-null (in this enum field) note: function pointers must be non-null (in this field of the only potentially inhabited enum variant)
--> $DIR/uninitialized-zeroed.rs:18:28 --> $DIR/invalid_value.rs:18:28
| |
LL | enum WrapEnum<T> { Wrapped(T) } LL | enum WrapEnum<T> { Wrapped(T) }
| ^ | ^
error: the type `WrapEnum<fn()>` does not permit being left uninitialized error: the type `WrapEnum<fn()>` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:73:36 --> $DIR/invalid_value.rs:83:36
| |
LL | let _val: WrapEnum<fn()> = mem::uninitialized(); LL | let _val: WrapEnum<fn()> = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -249,14 +257,14 @@ LL | let _val: WrapEnum<fn()> = mem::uninitialized();
| this code causes undefined behavior when executed | this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
note: function pointers must be non-null (in this enum field) note: function pointers must be non-null (in this field of the only potentially inhabited enum variant)
--> $DIR/uninitialized-zeroed.rs:18:28 --> $DIR/invalid_value.rs:18:28
| |
LL | enum WrapEnum<T> { Wrapped(T) } LL | enum WrapEnum<T> { Wrapped(T) }
| ^ | ^
error: the type `Wrap<(RefPair, i32)>` does not permit zero-initialization error: the type `Wrap<(RefPair, i32)>` does not permit zero-initialization
--> $DIR/uninitialized-zeroed.rs:75:42 --> $DIR/invalid_value.rs:85:42
| |
LL | let _val: Wrap<(RefPair, i32)> = mem::zeroed(); LL | let _val: Wrap<(RefPair, i32)> = mem::zeroed();
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -265,13 +273,13 @@ LL | let _val: Wrap<(RefPair, i32)> = mem::zeroed();
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
note: references must be non-null (in this struct field) note: references must be non-null (in this struct field)
--> $DIR/uninitialized-zeroed.rs:15:16 --> $DIR/invalid_value.rs:15:16
| |
LL | struct RefPair((&'static i32, i32)); LL | struct RefPair((&'static i32, i32));
| ^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^
error: the type `Wrap<(RefPair, i32)>` does not permit being left uninitialized error: the type `Wrap<(RefPair, i32)>` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:76:42 --> $DIR/invalid_value.rs:86:42
| |
LL | let _val: Wrap<(RefPair, i32)> = mem::uninitialized(); LL | let _val: Wrap<(RefPair, i32)> = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -280,13 +288,13 @@ LL | let _val: Wrap<(RefPair, i32)> = mem::uninitialized();
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
note: references must be non-null (in this struct field) note: references must be non-null (in this struct field)
--> $DIR/uninitialized-zeroed.rs:15:16 --> $DIR/invalid_value.rs:15:16
| |
LL | struct RefPair((&'static i32, i32)); LL | struct RefPair((&'static i32, i32));
| ^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^
error: the type `NonNull<i32>` does not permit zero-initialization error: the type `NonNull<i32>` does not permit zero-initialization
--> $DIR/uninitialized-zeroed.rs:78:34 --> $DIR/invalid_value.rs:88:34
| |
LL | let _val: NonNull<i32> = mem::zeroed(); LL | let _val: NonNull<i32> = mem::zeroed();
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -297,7 +305,7 @@ LL | let _val: NonNull<i32> = mem::zeroed();
= note: `std::ptr::NonNull<i32>` must be non-null = note: `std::ptr::NonNull<i32>` must be non-null
error: the type `NonNull<i32>` does not permit being left uninitialized error: the type `NonNull<i32>` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:79:34 --> $DIR/invalid_value.rs:89:34
| |
LL | let _val: NonNull<i32> = mem::uninitialized(); LL | let _val: NonNull<i32> = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -308,7 +316,7 @@ LL | let _val: NonNull<i32> = mem::uninitialized();
= note: `std::ptr::NonNull<i32>` must be non-null = note: `std::ptr::NonNull<i32>` must be non-null
error: the type `*const dyn Send` does not permit zero-initialization error: the type `*const dyn Send` does not permit zero-initialization
--> $DIR/uninitialized-zeroed.rs:81:37 --> $DIR/invalid_value.rs:91:37
| |
LL | let _val: *const dyn Send = mem::zeroed(); LL | let _val: *const dyn Send = mem::zeroed();
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -319,7 +327,7 @@ LL | let _val: *const dyn Send = mem::zeroed();
= note: the vtable of a wide raw pointer must be non-null = note: the vtable of a wide raw pointer must be non-null
error: the type `*const dyn Send` does not permit being left uninitialized error: the type `*const dyn Send` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:82:37 --> $DIR/invalid_value.rs:92:37
| |
LL | let _val: *const dyn Send = mem::uninitialized(); LL | let _val: *const dyn Send = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -330,7 +338,7 @@ LL | let _val: *const dyn Send = mem::uninitialized();
= note: the vtable of a wide raw pointer must be non-null = note: the vtable of a wide raw pointer must be non-null
error: the type `[fn(); 2]` does not permit zero-initialization error: the type `[fn(); 2]` does not permit zero-initialization
--> $DIR/uninitialized-zeroed.rs:84:31 --> $DIR/invalid_value.rs:94:31
| |
LL | let _val: [fn(); 2] = mem::zeroed(); LL | let _val: [fn(); 2] = mem::zeroed();
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -341,7 +349,7 @@ LL | let _val: [fn(); 2] = mem::zeroed();
= note: function pointers must be non-null = note: function pointers must be non-null
error: the type `[fn(); 2]` does not permit being left uninitialized error: the type `[fn(); 2]` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:85:31 --> $DIR/invalid_value.rs:95:31
| |
LL | let _val: [fn(); 2] = mem::uninitialized(); LL | let _val: [fn(); 2] = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -351,8 +359,68 @@ LL | let _val: [fn(); 2] = mem::uninitialized();
| |
= note: function pointers must be non-null = note: function pointers must be non-null
error: the type `TwoUninhabited` does not permit zero-initialization
--> $DIR/invalid_value.rs:97:36
|
LL | let _val: TwoUninhabited = mem::zeroed();
| ^^^^^^^^^^^^^
| |
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
note: enums with no inhabited variants have no valid value
--> $DIR/invalid_value.rs:42:1
|
LL | enum TwoUninhabited {
| ^^^^^^^^^^^^^^^^^^^
error: the type `TwoUninhabited` does not permit being left uninitialized
--> $DIR/invalid_value.rs:98:36
|
LL | let _val: TwoUninhabited = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^
| |
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
note: enums with no inhabited variants have no valid value
--> $DIR/invalid_value.rs:42:1
|
LL | enum TwoUninhabited {
| ^^^^^^^^^^^^^^^^^^^
error: the type `OneFruitNonZero` does not permit zero-initialization
--> $DIR/invalid_value.rs:100:37
|
LL | let _val: OneFruitNonZero = mem::zeroed();
| ^^^^^^^^^^^^^
| |
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
note: `std::num::NonZeroU32` must be non-null (in this field of the only potentially inhabited enum variant)
--> $DIR/invalid_value.rs:39:12
|
LL | Banana(NonZeroU32),
| ^^^^^^^^^^
error: the type `OneFruitNonZero` does not permit being left uninitialized
--> $DIR/invalid_value.rs:101:37
|
LL | let _val: OneFruitNonZero = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^
| |
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
note: `std::num::NonZeroU32` must be non-null (in this field of the only potentially inhabited enum variant)
--> $DIR/invalid_value.rs:39:12
|
LL | Banana(NonZeroU32),
| ^^^^^^^^^^
error: the type `bool` does not permit being left uninitialized error: the type `bool` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:89:26 --> $DIR/invalid_value.rs:105:26
| |
LL | let _val: bool = mem::uninitialized(); LL | let _val: bool = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -363,7 +431,7 @@ LL | let _val: bool = mem::uninitialized();
= note: booleans must be either `true` or `false` = note: booleans must be either `true` or `false`
error: the type `Wrap<char>` does not permit being left uninitialized error: the type `Wrap<char>` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:92:32 --> $DIR/invalid_value.rs:108:32
| |
LL | let _val: Wrap<char> = mem::uninitialized(); LL | let _val: Wrap<char> = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -372,13 +440,13 @@ LL | let _val: Wrap<char> = mem::uninitialized();
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
note: characters must be a valid Unicode codepoint (in this struct field) note: characters must be a valid Unicode codepoint (in this struct field)
--> $DIR/uninitialized-zeroed.rs:17:18 --> $DIR/invalid_value.rs:17:18
| |
LL | struct Wrap<T> { wrapped: T } LL | struct Wrap<T> { wrapped: T }
| ^^^^^^^^^^ | ^^^^^^^^^^
error: the type `NonBig` does not permit being left uninitialized error: the type `NonBig` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:95:28 --> $DIR/invalid_value.rs:111:28
| |
LL | let _val: NonBig = mem::uninitialized(); LL | let _val: NonBig = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -389,7 +457,7 @@ LL | let _val: NonBig = mem::uninitialized();
= note: `NonBig` must be initialized inside its custom valid range = note: `NonBig` must be initialized inside its custom valid range
error: the type `Fruit` does not permit being left uninitialized error: the type `Fruit` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:98:27 --> $DIR/invalid_value.rs:114:27
| |
LL | let _val: Fruit = mem::uninitialized(); LL | let _val: Fruit = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -397,14 +465,14 @@ LL | let _val: Fruit = mem::uninitialized();
| this code causes undefined behavior when executed | this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
note: enums have to be initialized to a variant note: enums with multiple inhabited variants have to be initialized to a variant
--> $DIR/uninitialized-zeroed.rs:26:1 --> $DIR/invalid_value.rs:26:1
| |
LL | enum Fruit { LL | enum Fruit {
| ^^^^^^^^^^ | ^^^^^^^^^^
error: the type `[bool; 2]` does not permit being left uninitialized error: the type `[bool; 2]` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:101:31 --> $DIR/invalid_value.rs:117:31
| |
LL | let _val: [bool; 2] = mem::uninitialized(); LL | let _val: [bool; 2] = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -415,7 +483,7 @@ LL | let _val: [bool; 2] = mem::uninitialized();
= note: booleans must be either `true` or `false` = note: booleans must be either `true` or `false`
error: the type `i32` does not permit being left uninitialized error: the type `i32` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:104:25 --> $DIR/invalid_value.rs:120:25
| |
LL | let _val: i32 = mem::uninitialized(); LL | let _val: i32 = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -426,7 +494,7 @@ LL | let _val: i32 = mem::uninitialized();
= note: integers must not be uninitialized = note: integers must not be uninitialized
error: the type `f32` does not permit being left uninitialized error: the type `f32` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:107:25 --> $DIR/invalid_value.rs:123:25
| |
LL | let _val: f32 = mem::uninitialized(); LL | let _val: f32 = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -437,7 +505,7 @@ LL | let _val: f32 = mem::uninitialized();
= note: floats must not be uninitialized = note: floats must not be uninitialized
error: the type `*const ()` does not permit being left uninitialized error: the type `*const ()` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:110:31 --> $DIR/invalid_value.rs:126:31
| |
LL | let _val: *const () = mem::uninitialized(); LL | let _val: *const () = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -448,7 +516,7 @@ LL | let _val: *const () = mem::uninitialized();
= note: raw pointers must not be uninitialized = note: raw pointers must not be uninitialized
error: the type `*const [()]` does not permit being left uninitialized error: the type `*const [()]` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:113:33 --> $DIR/invalid_value.rs:129:33
| |
LL | let _val: *const [()] = mem::uninitialized(); LL | let _val: *const [()] = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
@ -458,8 +526,23 @@ LL | let _val: *const [()] = mem::uninitialized();
| |
= note: raw pointers must not be uninitialized = note: raw pointers must not be uninitialized
error: the type `Result<i32, i32>` does not permit being left uninitialized
--> $DIR/invalid_value.rs:134:38
|
LL | let _val: Result<i32, i32> = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^
| |
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
note: enums with multiple inhabited variants have to be initialized to a variant
--> $SRC_DIR/core/src/result.rs:LL:COL
|
LL | pub enum Result<T, E> {
| ^^^^^^^^^^^^^^^^^^^^^
error: the type `&i32` does not permit zero-initialization error: the type `&i32` does not permit zero-initialization
--> $DIR/uninitialized-zeroed.rs:116:34 --> $DIR/invalid_value.rs:142:34
| |
LL | let _val: &'static i32 = mem::transmute(0usize); LL | let _val: &'static i32 = mem::transmute(0usize);
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
@ -470,7 +553,7 @@ LL | let _val: &'static i32 = mem::transmute(0usize);
= note: references must be non-null = note: references must be non-null
error: the type `&[i32]` does not permit zero-initialization error: the type `&[i32]` does not permit zero-initialization
--> $DIR/uninitialized-zeroed.rs:117:36 --> $DIR/invalid_value.rs:143:36
| |
LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize)); LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -481,7 +564,7 @@ LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize));
= note: references must be non-null = note: references must be non-null
error: the type `NonZeroU32` does not permit zero-initialization error: the type `NonZeroU32` does not permit zero-initialization
--> $DIR/uninitialized-zeroed.rs:118:32 --> $DIR/invalid_value.rs:144:32
| |
LL | let _val: NonZeroU32 = mem::transmute(0); LL | let _val: NonZeroU32 = mem::transmute(0);
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
@ -492,7 +575,7 @@ LL | let _val: NonZeroU32 = mem::transmute(0);
= note: `std::num::NonZeroU32` must be non-null = note: `std::num::NonZeroU32` must be non-null
error: the type `NonNull<i32>` does not permit zero-initialization error: the type `NonNull<i32>` does not permit zero-initialization
--> $DIR/uninitialized-zeroed.rs:121:34 --> $DIR/invalid_value.rs:147:34
| |
LL | let _val: NonNull<i32> = MaybeUninit::zeroed().assume_init(); LL | let _val: NonNull<i32> = MaybeUninit::zeroed().assume_init();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -503,7 +586,7 @@ LL | let _val: NonNull<i32> = MaybeUninit::zeroed().assume_init();
= note: `std::ptr::NonNull<i32>` must be non-null = note: `std::ptr::NonNull<i32>` must be non-null
error: the type `NonNull<i32>` does not permit being left uninitialized error: the type `NonNull<i32>` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:122:34 --> $DIR/invalid_value.rs:148:34
| |
LL | let _val: NonNull<i32> = MaybeUninit::uninit().assume_init(); LL | let _val: NonNull<i32> = MaybeUninit::uninit().assume_init();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -514,7 +597,7 @@ LL | let _val: NonNull<i32> = MaybeUninit::uninit().assume_init();
= note: `std::ptr::NonNull<i32>` must be non-null = note: `std::ptr::NonNull<i32>` must be non-null
error: the type `bool` does not permit being left uninitialized error: the type `bool` does not permit being left uninitialized
--> $DIR/uninitialized-zeroed.rs:123:26 --> $DIR/invalid_value.rs:149:26
| |
LL | let _val: bool = MaybeUninit::uninit().assume_init(); LL | let _val: bool = MaybeUninit::uninit().assume_init();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -524,5 +607,5 @@ LL | let _val: bool = MaybeUninit::uninit().assume_init();
| |
= note: booleans must be either `true` or `false` = note: booleans must be either `true` or `false`
error: aborting due to 43 previous errors error: aborting due to 48 previous errors

View file

@ -59,7 +59,11 @@ LL | static VOID2: Void = unsafe { std::mem::transmute(()) };
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
= note: `#[warn(invalid_value)]` on by default = note: `#[warn(invalid_value)]` on by default
= note: enums with no variants have no valid value note: enums with no inhabited variants have no valid value
--> $DIR/uninhabited-static.rs:4:1
|
LL | enum Void {}
| ^^^^^^^^^
error[E0080]: could not evaluate static initializer error[E0080]: could not evaluate static initializer
--> $DIR/uninhabited-static.rs:16:32 --> $DIR/uninhabited-static.rs:16:32
@ -76,7 +80,11 @@ LL | static NEVER2: Void = unsafe { std::mem::transmute(()) };
| this code causes undefined behavior when executed | this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
= note: enums with no variants have no valid value note: enums with no inhabited variants have no valid value
--> $DIR/uninhabited-static.rs:4:1
|
LL | enum Void {}
| ^^^^^^^^^
error: aborting due to 6 previous errors; 2 warnings emitted error: aborting due to 6 previous errors; 2 warnings emitted