Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 1dd3611

Browse files
authoredDec 13, 2023
Rollup merge of #118871 - tmiasko:coroutine-maybe-uninit-fields, r=compiler-errors
Coroutine variant fields can be uninitialized Wrap coroutine variant fields in MaybeUninit to indicate that they might be uninitialized. Otherwise an uninhabited field will make the entire variant uninhabited and introduce undefined behaviour. The analogous issue in the prefix of coroutine layout was addressed by 6fae7f8.
2 parents dbc6ec6 + a48cebc commit 1dd3611

File tree

5 files changed

+58
-4
lines changed

5 files changed

+58
-4
lines changed
 

‎compiler/rustc_ty_utils/src/layout.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,10 @@ fn coroutine_layout<'tcx>(
831831
Assigned(_) => bug!("assignment does not match variant"),
832832
Ineligible(_) => false,
833833
})
834-
.map(|local| subst_field(info.field_tys[*local].ty));
834+
.map(|local| {
835+
let field_ty = subst_field(info.field_tys[*local].ty);
836+
Ty::new_maybe_uninit(tcx, field_ty)
837+
});
835838

836839
let mut variant = univariant_uninterned(
837840
cx,

‎tests/ui/async-await/future-sizes/async-awaiting-fut.stdout

+6
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,16 @@ print-type-size variant `Panicked`: 1024 bytes
5252
print-type-size upvar `.arg`: 1024 bytes
5353
print-type-size type: `std::mem::ManuallyDrop<bool>`: 1 bytes, alignment: 1 bytes
5454
print-type-size field `.value`: 1 bytes
55+
print-type-size type: `std::mem::ManuallyDrop<{async fn body@$DIR/async-awaiting-fut.rs:6:17: 6:19}>`: 1 bytes, alignment: 1 bytes
56+
print-type-size field `.value`: 1 bytes
5557
print-type-size type: `std::mem::MaybeUninit<bool>`: 1 bytes, alignment: 1 bytes
5658
print-type-size variant `MaybeUninit`: 1 bytes
5759
print-type-size field `.uninit`: 0 bytes
5860
print-type-size field `.value`: 1 bytes
61+
print-type-size type: `std::mem::MaybeUninit<{async fn body@$DIR/async-awaiting-fut.rs:6:17: 6:19}>`: 1 bytes, alignment: 1 bytes
62+
print-type-size variant `MaybeUninit`: 1 bytes
63+
print-type-size field `.uninit`: 0 bytes
64+
print-type-size field `.value`: 1 bytes
5965
print-type-size type: `std::task::Poll<()>`: 1 bytes, alignment: 1 bytes
6066
print-type-size discriminant: 1 bytes
6167
print-type-size variant `Ready`: 0 bytes

‎tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
error[E0391]: cycle detected when computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}`
1+
error[E0391]: cycle detected when computing layout of `core::mem::maybe_uninit::MaybeUninit<{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}>`
22
|
3-
= note: ...which requires computing layout of `<<A as First>::Second as Second>::{opaque#0}`...
4-
= note: ...which again requires computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}`, completing the cycle
3+
= note: ...which requires computing layout of `core::mem::manually_drop::ManuallyDrop<{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}>`...
4+
= note: ...which requires computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}`...
5+
= note: ...which requires computing layout of `core::mem::maybe_uninit::MaybeUninit<<<A as First>::Second as Second>::{opaque#0}>`...
6+
= note: ...which again requires computing layout of `core::mem::maybe_uninit::MaybeUninit<{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}>`, completing the cycle
57
= note: cycle used when computing layout of `{async block@$DIR/indirect-recursion-issue-112047.rs:6:13: 8:6}`
68
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
79

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Test that uninhabited saved local doesn't make the entire variant uninhabited.
2+
// run-pass
3+
#![allow(unused)]
4+
#![feature(assert_matches)]
5+
#![feature(coroutine_trait)]
6+
#![feature(coroutines)]
7+
#![feature(never_type)]
8+
use std::assert_matches::assert_matches;
9+
use std::ops::Coroutine;
10+
use std::ops::CoroutineState;
11+
use std::pin::Pin;
12+
13+
fn conjure<T>() -> T { loop {} }
14+
15+
fn run<T>(x: bool, y: bool) {
16+
let mut c = || {
17+
if x {
18+
let a : T;
19+
if y {
20+
a = conjure::<T>();
21+
}
22+
yield ();
23+
} else {
24+
let a : T;
25+
if y {
26+
a = conjure::<T>();
27+
}
28+
yield ();
29+
}
30+
};
31+
assert_matches!(Pin::new(&mut c).resume(()), CoroutineState::Yielded(()));
32+
assert_matches!(Pin::new(&mut c).resume(()), CoroutineState::Complete(()));
33+
}
34+
35+
fn main() {
36+
run::<!>(false, false);
37+
}

‎tests/ui/print_type_sizes/coroutine_discr_placement.stdout

+6
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,9 @@ print-type-size padding: 3 bytes
99
print-type-size local `.z`: 4 bytes, alignment: 4 bytes
1010
print-type-size variant `Returned`: 0 bytes
1111
print-type-size variant `Panicked`: 0 bytes
12+
print-type-size type: `std::mem::ManuallyDrop<i32>`: 4 bytes, alignment: 4 bytes
13+
print-type-size field `.value`: 4 bytes
14+
print-type-size type: `std::mem::MaybeUninit<i32>`: 4 bytes, alignment: 4 bytes
15+
print-type-size variant `MaybeUninit`: 4 bytes
16+
print-type-size field `.uninit`: 0 bytes
17+
print-type-size field `.value`: 4 bytes

0 commit comments

Comments
 (0)
Failed to load comments.