Skip to content

Commit d13e8dd

Browse files
committed
Auto merge of #93165 - eholk:disable-generator-drop-tracking, r=nikomatsakis
Disable drop range tracking in generators Generator drop tracking caused an ICE for generators involving the Never type (Issue #93161). Since this breaks a test case with miri, we temporarily disable drop tracking so miri is unblocked while we properly fix the issue.
2 parents 10c4c4a + ead84d0 commit d13e8dd

File tree

7 files changed

+122
-1
lines changed

7 files changed

+122
-1
lines changed

compiler/rustc_typeck/src/check/generator_interior.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ use tracing::debug;
2222

2323
mod drop_ranges;
2424

25+
// FIXME(eholk): This flag is here to give a quick way to disable drop tracking in case we find
26+
// unexpected breakages while it's still new. It should be removed before too long. For example,
27+
// see #93161.
28+
const ENABLE_DROP_TRACKING: bool = false;
29+
2530
struct InteriorVisitor<'a, 'tcx> {
2631
fcx: &'a FnCtxt<'a, 'tcx>,
2732
types: FxIndexSet<ty::GeneratorInteriorTypeCause<'tcx>>,
@@ -77,7 +82,10 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
7782
yield_data.expr_and_pat_count, self.expr_count, source_span
7883
);
7984

80-
if self.drop_ranges.is_dropped_at(hir_id, yield_data.expr_and_pat_count)
85+
if ENABLE_DROP_TRACKING
86+
&& self
87+
.drop_ranges
88+
.is_dropped_at(hir_id, yield_data.expr_and_pat_count)
8189
{
8290
debug!("value is dropped at yield point; not recording");
8391
return false;

src/test/ui/async-await/async-fn-nonsend.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
// edition:2018
22
// compile-flags: --crate-type lib
33

4+
// FIXME(eholk): temporarily disabled while drop range tracking is disabled
5+
// (see generator_interior.rs:27)
6+
// ignore-test
7+
48
use std::{cell::RefCell, fmt::Debug, rc::Rc};
59

610
fn non_sync() -> impl Debug {

src/test/ui/async-await/unresolved_type_param.rs

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
// (rather than give a general error message)
44
// edition:2018
55

6+
// FIXME(eholk): temporarily disabled while drop range tracking is disabled
7+
// (see generator_interior.rs:27)
8+
// ignore-test
9+
610
async fn bar<T>() -> () {}
711

812
async fn foo() {

src/test/ui/generator/drop-control-flow.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
// build-pass
22

3+
// FIXME(eholk): temporarily disabled while drop range tracking is disabled
4+
// (see generator_interior.rs:27)
5+
// ignore-test
6+
37
// A test to ensure generators capture values that were conditionally dropped,
48
// and also that values that are dropped along all paths to a yield do not get
59
// included in the generator type.

src/test/ui/generator/issue-57478.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
// check-pass
22

3+
// FIXME(eholk): temporarily disabled while drop range tracking is disabled
4+
// (see generator_interior.rs:27)
5+
// ignore-test
6+
37
#![feature(negative_impls, generators)]
48

59
struct Foo;

src/test/ui/generator/issue-93161.rs

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// edition:2021
2+
// run-pass
3+
4+
#![feature(never_type)]
5+
6+
use std::future::Future;
7+
8+
// See if we can run a basic `async fn`
9+
pub async fn foo(x: &u32, y: u32) -> u32 {
10+
let y = &y;
11+
let z = 9;
12+
let z = &z;
13+
let y = async { *y + *z }.await;
14+
let a = 10;
15+
let a = &a;
16+
*x + y + *a
17+
}
18+
19+
async fn add(x: u32, y: u32) -> u32 {
20+
let a = async { x + y };
21+
a.await
22+
}
23+
24+
async fn build_aggregate(a: u32, b: u32, c: u32, d: u32) -> u32 {
25+
let x = (add(a, b).await, add(c, d).await);
26+
x.0 + x.1
27+
}
28+
29+
enum Never {}
30+
fn never() -> Never {
31+
panic!()
32+
}
33+
34+
async fn includes_never(crash: bool, x: u32) -> u32 {
35+
let mut result = async { x * x }.await;
36+
if !crash {
37+
return result;
38+
}
39+
#[allow(unused)]
40+
let bad = never();
41+
result *= async { x + x }.await;
42+
drop(bad);
43+
result
44+
}
45+
46+
async fn partial_init(x: u32) -> u32 {
47+
#[allow(unreachable_code)]
48+
let _x: (String, !) = (String::new(), return async { x + x }.await);
49+
}
50+
51+
async fn read_exact(_from: &mut &[u8], _to: &mut [u8]) -> Option<()> {
52+
Some(())
53+
}
54+
55+
async fn hello_world() {
56+
let data = [0u8; 1];
57+
let mut reader = &data[..];
58+
59+
let mut marker = [0u8; 1];
60+
read_exact(&mut reader, &mut marker).await.unwrap();
61+
}
62+
63+
fn run_fut<T>(fut: impl Future<Output = T>) -> T {
64+
use std::sync::Arc;
65+
use std::task::{Context, Poll, Wake, Waker};
66+
67+
struct MyWaker;
68+
impl Wake for MyWaker {
69+
fn wake(self: Arc<Self>) {
70+
unimplemented!()
71+
}
72+
}
73+
74+
let waker = Waker::from(Arc::new(MyWaker));
75+
let mut context = Context::from_waker(&waker);
76+
77+
let mut pinned = Box::pin(fut);
78+
loop {
79+
match pinned.as_mut().poll(&mut context) {
80+
Poll::Pending => continue,
81+
Poll::Ready(v) => return v,
82+
}
83+
}
84+
}
85+
86+
fn main() {
87+
let x = 5;
88+
assert_eq!(run_fut(foo(&x, 7)), 31);
89+
assert_eq!(run_fut(build_aggregate(1, 2, 3, 4)), 10);
90+
assert_eq!(run_fut(includes_never(false, 4)), 16);
91+
assert_eq!(run_fut(partial_init(4)), 8);
92+
run_fut(hello_world());
93+
}

src/test/ui/generator/partial-drop.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
// FIXME(eholk): temporarily disabled while drop range tracking is disabled
2+
// (see generator_interior.rs:27)
3+
// ignore-test
4+
15
#![feature(negative_impls, generators)]
26

37
struct Foo;

0 commit comments

Comments
 (0)