Auto merge of #130547 - workingjubilee:rollup-tw30khz, r=workingjubilee
Rollup of 3 pull requests Successful merges: - #130531 (Check params for unsafety in THIR) - #130533 (Never patterns constitute a read for unsafety) - #130542 (Stabilize const `MaybeUninit::as_mut_ptr`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
b7b9453ea7
@ -218,6 +218,13 @@ fn visit_inner_body(&mut self, def: LocalDefId) {
|
||||
warnings: self.warnings,
|
||||
suggest_unsafe_block: self.suggest_unsafe_block,
|
||||
};
|
||||
// params in THIR may be unsafe, e.g. a union pattern.
|
||||
for param in &inner_thir.params {
|
||||
if let Some(param_pat) = param.pat.as_deref() {
|
||||
inner_visitor.visit_pat(param_pat);
|
||||
}
|
||||
}
|
||||
// Visit the body.
|
||||
inner_visitor.visit_expr(&inner_thir[expr]);
|
||||
// Unsafe blocks can be used in the inner body, make sure to take it into account
|
||||
self.safety_context = inner_visitor.safety_context;
|
||||
@ -315,14 +322,15 @@ fn visit_pat(&mut self, pat: &'a Pat<'tcx>) {
|
||||
| PatKind::DerefPattern { .. }
|
||||
| PatKind::Range { .. }
|
||||
| PatKind::Slice { .. }
|
||||
| PatKind::Array { .. } => {
|
||||
| PatKind::Array { .. }
|
||||
// Never constitutes a witness of uninhabitedness.
|
||||
| PatKind::Never => {
|
||||
self.requires_unsafe(pat.span, AccessToUnionField);
|
||||
return; // we can return here since this already requires unsafe
|
||||
}
|
||||
// wildcard/never don't take anything
|
||||
// wildcard doesn't read anything.
|
||||
PatKind::Wild |
|
||||
PatKind::Never |
|
||||
// these just wrap other patterns
|
||||
// these just wrap other patterns, which we recurse on below.
|
||||
PatKind::Or { .. } |
|
||||
PatKind::InlineConstant { .. } |
|
||||
PatKind::AscribeUserType { .. } |
|
||||
@ -1032,6 +1040,13 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
|
||||
warnings: &mut warnings,
|
||||
suggest_unsafe_block: true,
|
||||
};
|
||||
// params in THIR may be unsafe, e.g. a union pattern.
|
||||
for param in &thir.params {
|
||||
if let Some(param_pat) = param.pat.as_deref() {
|
||||
visitor.visit_pat(param_pat);
|
||||
}
|
||||
}
|
||||
// Visit the body.
|
||||
visitor.visit_expr(&thir[expr]);
|
||||
|
||||
warnings.sort_by_key(|w| w.block_span);
|
||||
|
@ -110,7 +110,6 @@
|
||||
#![feature(const_cow_is_borrowed)]
|
||||
#![feature(const_eval_select)]
|
||||
#![feature(const_heap)]
|
||||
#![feature(const_maybe_uninit_as_mut_ptr)]
|
||||
#![feature(const_maybe_uninit_write)]
|
||||
#![feature(const_option)]
|
||||
#![feature(const_pin)]
|
||||
|
@ -132,7 +132,6 @@
|
||||
#![feature(const_ipv4)]
|
||||
#![feature(const_ipv6)]
|
||||
#![feature(const_likely)]
|
||||
#![feature(const_maybe_uninit_as_mut_ptr)]
|
||||
#![feature(const_maybe_uninit_assume_init)]
|
||||
#![feature(const_nonnull_new)]
|
||||
#![feature(const_num_midpoint)]
|
||||
|
@ -393,7 +393,6 @@ pub const fn uninit() -> MaybeUninit<T> {
|
||||
// These are OK to allow since we do not leak &mut to user-visible API
|
||||
#[rustc_allow_const_fn_unstable(const_mut_refs)]
|
||||
#[rustc_allow_const_fn_unstable(const_ptr_write)]
|
||||
#[rustc_allow_const_fn_unstable(const_maybe_uninit_as_mut_ptr)]
|
||||
#[rustc_const_stable(feature = "const_maybe_uninit_zeroed", since = "1.75.0")]
|
||||
pub const fn zeroed() -> MaybeUninit<T> {
|
||||
let mut u = MaybeUninit::<T>::uninit();
|
||||
@ -570,7 +569,11 @@ pub const fn as_ptr(&self) -> *const T {
|
||||
/// (Notice that the rules around references to uninitialized data are not finalized yet, but
|
||||
/// until they are, it is advisable to avoid them.)
|
||||
#[stable(feature = "maybe_uninit", since = "1.36.0")]
|
||||
#[rustc_const_unstable(feature = "const_maybe_uninit_as_mut_ptr", issue = "75251")]
|
||||
#[rustc_const_stable(
|
||||
feature = "const_maybe_uninit_as_mut_ptr",
|
||||
since = "CURRENT_RUSTC_VERSION"
|
||||
)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
|
||||
#[inline(always)]
|
||||
pub const fn as_mut_ptr(&mut self) -> *mut T {
|
||||
// `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer.
|
||||
|
@ -26,7 +26,6 @@
|
||||
#![feature(const_ipv4)]
|
||||
#![feature(const_ipv6)]
|
||||
#![feature(const_likely)]
|
||||
#![feature(const_maybe_uninit_as_mut_ptr)]
|
||||
#![feature(const_nonnull_new)]
|
||||
#![feature(const_option)]
|
||||
#![feature(const_option_ext)]
|
||||
|
@ -0,0 +1,16 @@
|
||||
// Make sure we consider `!` to be a union read.
|
||||
|
||||
#![feature(never_type, never_patterns)]
|
||||
//~^ WARN the feature `never_patterns` is incomplete
|
||||
|
||||
union U {
|
||||
a: !,
|
||||
b: usize,
|
||||
}
|
||||
|
||||
fn foo<T>(u: U) -> ! {
|
||||
let U { a: ! } = u;
|
||||
//~^ ERROR access to union field is unsafe
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,20 @@
|
||||
warning: the feature `never_patterns` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/never-pattern-is-a-read.rs:3:24
|
||||
|
|
||||
LL | #![feature(never_type, never_patterns)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #118155 <https://github.com/rust-lang/rust/issues/118155> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/never-pattern-is-a-read.rs:12:16
|
||||
|
|
||||
LL | let U { a: ! } = u;
|
||||
| ^ access to union field
|
||||
|
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error: aborting due to 1 previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
19
tests/ui/unsafe/union-pat-in-param.rs
Normal file
19
tests/ui/unsafe/union-pat-in-param.rs
Normal file
@ -0,0 +1,19 @@
|
||||
union U {
|
||||
a: &'static i32,
|
||||
b: usize,
|
||||
}
|
||||
|
||||
fn fun(U { a }: U) {
|
||||
//~^ ERROR access to union field is unsafe
|
||||
dbg!(*a);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
fun(U { b: 0 });
|
||||
|
||||
let closure = |U { a }| {
|
||||
//~^ ERROR access to union field is unsafe
|
||||
dbg!(*a);
|
||||
};
|
||||
closure(U { b: 0 });
|
||||
}
|
19
tests/ui/unsafe/union-pat-in-param.stderr
Normal file
19
tests/ui/unsafe/union-pat-in-param.stderr
Normal file
@ -0,0 +1,19 @@
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-pat-in-param.rs:6:12
|
||||
|
|
||||
LL | fn fun(U { a }: U) {
|
||||
| ^ access to union field
|
||||
|
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-pat-in-param.rs:14:24
|
||||
|
|
||||
LL | let closure = |U { a }| {
|
||||
| ^ access to union field
|
||||
|
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
Loading…
Reference in New Issue
Block a user