Skip to content

Commit b7b9453

Browse files
committed
Auto merge of rust-lang#130547 - workingjubilee:rollup-tw30khz, r=workingjubilee
Rollup of 3 pull requests Successful merges: - rust-lang#130531 (Check params for unsafety in THIR) - rust-lang#130533 (Never patterns constitute a read for unsafety) - rust-lang#130542 (Stabilize const `MaybeUninit::as_mut_ptr`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents f8192ba + 0ad2a52 commit b7b9453

File tree

9 files changed

+98
-9
lines changed

9 files changed

+98
-9
lines changed

compiler/rustc_mir_build/src/check_unsafety.rs

+19-4
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,13 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
218218
warnings: self.warnings,
219219
suggest_unsafe_block: self.suggest_unsafe_block,
220220
};
221+
// params in THIR may be unsafe, e.g. a union pattern.
222+
for param in &inner_thir.params {
223+
if let Some(param_pat) = param.pat.as_deref() {
224+
inner_visitor.visit_pat(param_pat);
225+
}
226+
}
227+
// Visit the body.
221228
inner_visitor.visit_expr(&inner_thir[expr]);
222229
// Unsafe blocks can be used in the inner body, make sure to take it into account
223230
self.safety_context = inner_visitor.safety_context;
@@ -315,14 +322,15 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
315322
| PatKind::DerefPattern { .. }
316323
| PatKind::Range { .. }
317324
| PatKind::Slice { .. }
318-
| PatKind::Array { .. } => {
325+
| PatKind::Array { .. }
326+
// Never constitutes a witness of uninhabitedness.
327+
| PatKind::Never => {
319328
self.requires_unsafe(pat.span, AccessToUnionField);
320329
return; // we can return here since this already requires unsafe
321330
}
322-
// wildcard/never don't take anything
331+
// wildcard doesn't read anything.
323332
PatKind::Wild |
324-
PatKind::Never |
325-
// these just wrap other patterns
333+
// these just wrap other patterns, which we recurse on below.
326334
PatKind::Or { .. } |
327335
PatKind::InlineConstant { .. } |
328336
PatKind::AscribeUserType { .. } |
@@ -1032,6 +1040,13 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
10321040
warnings: &mut warnings,
10331041
suggest_unsafe_block: true,
10341042
};
1043+
// params in THIR may be unsafe, e.g. a union pattern.
1044+
for param in &thir.params {
1045+
if let Some(param_pat) = param.pat.as_deref() {
1046+
visitor.visit_pat(param_pat);
1047+
}
1048+
}
1049+
// Visit the body.
10351050
visitor.visit_expr(&thir[expr]);
10361051

10371052
warnings.sort_by_key(|w| w.block_span);

library/alloc/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@
110110
#![feature(const_cow_is_borrowed)]
111111
#![feature(const_eval_select)]
112112
#![feature(const_heap)]
113-
#![feature(const_maybe_uninit_as_mut_ptr)]
114113
#![feature(const_maybe_uninit_write)]
115114
#![feature(const_option)]
116115
#![feature(const_pin)]

library/core/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@
132132
#![feature(const_ipv4)]
133133
#![feature(const_ipv6)]
134134
#![feature(const_likely)]
135-
#![feature(const_maybe_uninit_as_mut_ptr)]
136135
#![feature(const_maybe_uninit_assume_init)]
137136
#![feature(const_nonnull_new)]
138137
#![feature(const_num_midpoint)]

library/core/src/mem/maybe_uninit.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,6 @@ impl<T> MaybeUninit<T> {
393393
// These are OK to allow since we do not leak &mut to user-visible API
394394
#[rustc_allow_const_fn_unstable(const_mut_refs)]
395395
#[rustc_allow_const_fn_unstable(const_ptr_write)]
396-
#[rustc_allow_const_fn_unstable(const_maybe_uninit_as_mut_ptr)]
397396
#[rustc_const_stable(feature = "const_maybe_uninit_zeroed", since = "1.75.0")]
398397
pub const fn zeroed() -> MaybeUninit<T> {
399398
let mut u = MaybeUninit::<T>::uninit();
@@ -570,7 +569,11 @@ impl<T> MaybeUninit<T> {
570569
/// (Notice that the rules around references to uninitialized data are not finalized yet, but
571570
/// until they are, it is advisable to avoid them.)
572571
#[stable(feature = "maybe_uninit", since = "1.36.0")]
573-
#[rustc_const_unstable(feature = "const_maybe_uninit_as_mut_ptr", issue = "75251")]
572+
#[rustc_const_stable(
573+
feature = "const_maybe_uninit_as_mut_ptr",
574+
since = "CURRENT_RUSTC_VERSION"
575+
)]
576+
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
574577
#[inline(always)]
575578
pub const fn as_mut_ptr(&mut self) -> *mut T {
576579
// `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer.

library/core/tests/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
#![feature(const_ipv4)]
2727
#![feature(const_ipv6)]
2828
#![feature(const_likely)]
29-
#![feature(const_maybe_uninit_as_mut_ptr)]
3029
#![feature(const_nonnull_new)]
3130
#![feature(const_option)]
3231
#![feature(const_option_ext)]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Make sure we consider `!` to be a union read.
2+
3+
#![feature(never_type, never_patterns)]
4+
//~^ WARN the feature `never_patterns` is incomplete
5+
6+
union U {
7+
a: !,
8+
b: usize,
9+
}
10+
11+
fn foo<T>(u: U) -> ! {
12+
let U { a: ! } = u;
13+
//~^ ERROR access to union field is unsafe
14+
}
15+
16+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
warning: the feature `never_patterns` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/never-pattern-is-a-read.rs:3:24
3+
|
4+
LL | #![feature(never_type, never_patterns)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #118155 <https://github.com/rust-lang/rust/issues/118155> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error[E0133]: access to union field is unsafe and requires unsafe function or block
11+
--> $DIR/never-pattern-is-a-read.rs:12:16
12+
|
13+
LL | let U { a: ! } = u;
14+
| ^ access to union field
15+
|
16+
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
17+
18+
error: aborting due to 1 previous error; 1 warning emitted
19+
20+
For more information about this error, try `rustc --explain E0133`.

tests/ui/unsafe/union-pat-in-param.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
union U {
2+
a: &'static i32,
3+
b: usize,
4+
}
5+
6+
fn fun(U { a }: U) {
7+
//~^ ERROR access to union field is unsafe
8+
dbg!(*a);
9+
}
10+
11+
fn main() {
12+
fun(U { b: 0 });
13+
14+
let closure = |U { a }| {
15+
//~^ ERROR access to union field is unsafe
16+
dbg!(*a);
17+
};
18+
closure(U { b: 0 });
19+
}
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0133]: access to union field is unsafe and requires unsafe function or block
2+
--> $DIR/union-pat-in-param.rs:6:12
3+
|
4+
LL | fn fun(U { a }: U) {
5+
| ^ access to union field
6+
|
7+
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
8+
9+
error[E0133]: access to union field is unsafe and requires unsafe function or block
10+
--> $DIR/union-pat-in-param.rs:14:24
11+
|
12+
LL | let closure = |U { a }| {
13+
| ^ access to union field
14+
|
15+
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
16+
17+
error: aborting due to 2 previous errors
18+
19+
For more information about this error, try `rustc --explain E0133`.

0 commit comments

Comments
 (0)