Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions library/core/src/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -705,9 +705,24 @@ pub const unsafe fn zeroed<T>() -> T {
/// Therefore, it is immediate undefined behavior to call this function on nearly all types,
/// including integer types and arrays of integer types, and even if the result is unused.
///
/// # Safety
///
/// This function is highly unsafe, as calling this function on nearly all types causes
/// undefined behavior. You should **always** prefer using [`MaybeUninit<T>`] instead.
///
/// If you absolutely must use this function, the following conditions must be upheld:
///
/// - `T` must be *valid* with any sequence of bytes of the appropriate length,
/// initialized or uninitialized.
Comment on lines +715 to +716
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should hint that non-ZST T effectively needs to be all MaybeUninit to account for the uninitialized requirement. Not sure about best wording but maybe something like:

"... That is, if T is not a ZST, it must be MaybeUninit or an ADT containing only MaybeUninit and padding."

Copy link
Contributor Author

@CieriA CieriA Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, but wouldn't that suggest a correct usage of this function? I removed that part because it would suggest that using uninitialized() with ZSTs is acceptable (and you said that we should discourage usage of uninitialized() by not providing any example, that's why I kept the safety conditions a bit more "abstract"). What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think mentioning the MaybeUninit requirement suggests anything more than what is already there, just makes it more obvious that this isn't sound even for POD types (since that's been a confusion point in the past). Not mentioning ZSTs seems reasonable though.

/// - `T` must be *[inhabited]*, i.e. possible to construct. This means that types
/// like zero-variant enums and [`!`] are unsound to construct with this function.
/// - You must use the value only in ways which do not violate any *safety*
/// invariants of the type.
///
/// [uninit]: MaybeUninit::uninit
/// [assume_init]: MaybeUninit::assume_init
/// [inv]: MaybeUninit#initialization-invariant
/// [inhabited]: https://doc.rust-lang.org/reference/glossary.html#inhabited
#[inline(always)]
#[must_use]
#[deprecated(since = "1.39.0", note = "use `mem::MaybeUninit` instead")]
Expand Down
36 changes: 18 additions & 18 deletions tests/ui/thir-print/offset_of.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ body:
}
)
else_block: None
hir_id: HirId(DefId(offset_of::concrete).10)
span: $DIR/offset_of.rs:37:5: 1440:57 (#0)
lint_level: Explicit(HirId(DefId(offset_of::concrete).10))
span: $DIR/offset_of.rs:37:5: 1455:57 (#0)
}
}
Stmt {
Expand Down Expand Up @@ -116,8 +116,8 @@ body:
}
)
else_block: None
hir_id: HirId(DefId(offset_of::concrete).20)
span: $DIR/offset_of.rs:38:5: 1440:57 (#0)
lint_level: Explicit(HirId(DefId(offset_of::concrete).20))
span: $DIR/offset_of.rs:38:5: 1455:57 (#0)
}
}
Stmt {
Expand Down Expand Up @@ -165,8 +165,8 @@ body:
}
)
else_block: None
hir_id: HirId(DefId(offset_of::concrete).30)
span: $DIR/offset_of.rs:39:5: 1440:57 (#0)
lint_level: Explicit(HirId(DefId(offset_of::concrete).30))
span: $DIR/offset_of.rs:39:5: 1455:57 (#0)
}
}
Stmt {
Expand Down Expand Up @@ -214,8 +214,8 @@ body:
}
)
else_block: None
hir_id: HirId(DefId(offset_of::concrete).40)
span: $DIR/offset_of.rs:40:5: 1440:57 (#0)
lint_level: Explicit(HirId(DefId(offset_of::concrete).40))
span: $DIR/offset_of.rs:40:5: 1455:57 (#0)
}
}
Stmt {
Expand Down Expand Up @@ -263,8 +263,8 @@ body:
}
)
else_block: None
hir_id: HirId(DefId(offset_of::concrete).50)
span: $DIR/offset_of.rs:41:5: 1440:57 (#0)
lint_level: Explicit(HirId(DefId(offset_of::concrete).50))
span: $DIR/offset_of.rs:41:5: 1455:57 (#0)
}
}
]
Expand Down Expand Up @@ -863,8 +863,8 @@ body:
}
)
else_block: None
hir_id: HirId(DefId(offset_of::generic).12)
span: $DIR/offset_of.rs:45:5: 1440:57 (#0)
lint_level: Explicit(HirId(DefId(offset_of::generic).12))
span: $DIR/offset_of.rs:45:5: 1455:57 (#0)
}
}
Stmt {
Expand Down Expand Up @@ -912,8 +912,8 @@ body:
}
)
else_block: None
hir_id: HirId(DefId(offset_of::generic).24)
span: $DIR/offset_of.rs:46:5: 1440:57 (#0)
lint_level: Explicit(HirId(DefId(offset_of::generic).24))
span: $DIR/offset_of.rs:46:5: 1455:57 (#0)
}
}
Stmt {
Expand Down Expand Up @@ -961,8 +961,8 @@ body:
}
)
else_block: None
hir_id: HirId(DefId(offset_of::generic).36)
span: $DIR/offset_of.rs:47:5: 1440:57 (#0)
lint_level: Explicit(HirId(DefId(offset_of::generic).36))
span: $DIR/offset_of.rs:47:5: 1455:57 (#0)
}
}
Stmt {
Expand Down Expand Up @@ -1010,8 +1010,8 @@ body:
}
)
else_block: None
hir_id: HirId(DefId(offset_of::generic).48)
span: $DIR/offset_of.rs:48:5: 1440:57 (#0)
lint_level: Explicit(HirId(DefId(offset_of::generic).48))
span: $DIR/offset_of.rs:48:5: 1455:57 (#0)
}
}
]
Expand Down
Loading