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.
This commit is contained in:
commit
d13e8dd41d
@ -22,6 +22,11 @@ use tracing::debug;
|
||||
|
||||
mod drop_ranges;
|
||||
|
||||
// FIXME(eholk): This flag is here to give a quick way to disable drop tracking in case we find
|
||||
// unexpected breakages while it's still new. It should be removed before too long. For example,
|
||||
// see #93161.
|
||||
const ENABLE_DROP_TRACKING: bool = false;
|
||||
|
||||
struct InteriorVisitor<'a, 'tcx> {
|
||||
fcx: &'a FnCtxt<'a, 'tcx>,
|
||||
types: FxIndexSet<ty::GeneratorInteriorTypeCause<'tcx>>,
|
||||
@ -77,7 +82,10 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
|
||||
yield_data.expr_and_pat_count, self.expr_count, source_span
|
||||
);
|
||||
|
||||
if self.drop_ranges.is_dropped_at(hir_id, yield_data.expr_and_pat_count)
|
||||
if ENABLE_DROP_TRACKING
|
||||
&& self
|
||||
.drop_ranges
|
||||
.is_dropped_at(hir_id, yield_data.expr_and_pat_count)
|
||||
{
|
||||
debug!("value is dropped at yield point; not recording");
|
||||
return false;
|
||||
|
@ -1,6 +1,10 @@
|
||||
// edition:2018
|
||||
// compile-flags: --crate-type lib
|
||||
|
||||
// FIXME(eholk): temporarily disabled while drop range tracking is disabled
|
||||
// (see generator_interior.rs:27)
|
||||
// ignore-test
|
||||
|
||||
use std::{cell::RefCell, fmt::Debug, rc::Rc};
|
||||
|
||||
fn non_sync() -> impl Debug {
|
||||
|
@ -3,6 +3,10 @@
|
||||
// (rather than give a general error message)
|
||||
// edition:2018
|
||||
|
||||
// FIXME(eholk): temporarily disabled while drop range tracking is disabled
|
||||
// (see generator_interior.rs:27)
|
||||
// ignore-test
|
||||
|
||||
async fn bar<T>() -> () {}
|
||||
|
||||
async fn foo() {
|
||||
|
@ -1,5 +1,9 @@
|
||||
// build-pass
|
||||
|
||||
// FIXME(eholk): temporarily disabled while drop range tracking is disabled
|
||||
// (see generator_interior.rs:27)
|
||||
// ignore-test
|
||||
|
||||
// A test to ensure generators capture values that were conditionally dropped,
|
||||
// and also that values that are dropped along all paths to a yield do not get
|
||||
// included in the generator type.
|
||||
|
@ -1,5 +1,9 @@
|
||||
// check-pass
|
||||
|
||||
// FIXME(eholk): temporarily disabled while drop range tracking is disabled
|
||||
// (see generator_interior.rs:27)
|
||||
// ignore-test
|
||||
|
||||
#![feature(negative_impls, generators)]
|
||||
|
||||
struct Foo;
|
||||
|
93
src/test/ui/generator/issue-93161.rs
Normal file
93
src/test/ui/generator/issue-93161.rs
Normal file
@ -0,0 +1,93 @@
|
||||
// edition:2021
|
||||
// run-pass
|
||||
|
||||
#![feature(never_type)]
|
||||
|
||||
use std::future::Future;
|
||||
|
||||
// See if we can run a basic `async fn`
|
||||
pub async fn foo(x: &u32, y: u32) -> u32 {
|
||||
let y = &y;
|
||||
let z = 9;
|
||||
let z = &z;
|
||||
let y = async { *y + *z }.await;
|
||||
let a = 10;
|
||||
let a = &a;
|
||||
*x + y + *a
|
||||
}
|
||||
|
||||
async fn add(x: u32, y: u32) -> u32 {
|
||||
let a = async { x + y };
|
||||
a.await
|
||||
}
|
||||
|
||||
async fn build_aggregate(a: u32, b: u32, c: u32, d: u32) -> u32 {
|
||||
let x = (add(a, b).await, add(c, d).await);
|
||||
x.0 + x.1
|
||||
}
|
||||
|
||||
enum Never {}
|
||||
fn never() -> Never {
|
||||
panic!()
|
||||
}
|
||||
|
||||
async fn includes_never(crash: bool, x: u32) -> u32 {
|
||||
let mut result = async { x * x }.await;
|
||||
if !crash {
|
||||
return result;
|
||||
}
|
||||
#[allow(unused)]
|
||||
let bad = never();
|
||||
result *= async { x + x }.await;
|
||||
drop(bad);
|
||||
result
|
||||
}
|
||||
|
||||
async fn partial_init(x: u32) -> u32 {
|
||||
#[allow(unreachable_code)]
|
||||
let _x: (String, !) = (String::new(), return async { x + x }.await);
|
||||
}
|
||||
|
||||
async fn read_exact(_from: &mut &[u8], _to: &mut [u8]) -> Option<()> {
|
||||
Some(())
|
||||
}
|
||||
|
||||
async fn hello_world() {
|
||||
let data = [0u8; 1];
|
||||
let mut reader = &data[..];
|
||||
|
||||
let mut marker = [0u8; 1];
|
||||
read_exact(&mut reader, &mut marker).await.unwrap();
|
||||
}
|
||||
|
||||
fn run_fut<T>(fut: impl Future<Output = T>) -> T {
|
||||
use std::sync::Arc;
|
||||
use std::task::{Context, Poll, Wake, Waker};
|
||||
|
||||
struct MyWaker;
|
||||
impl Wake for MyWaker {
|
||||
fn wake(self: Arc<Self>) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
let waker = Waker::from(Arc::new(MyWaker));
|
||||
let mut context = Context::from_waker(&waker);
|
||||
|
||||
let mut pinned = Box::pin(fut);
|
||||
loop {
|
||||
match pinned.as_mut().poll(&mut context) {
|
||||
Poll::Pending => continue,
|
||||
Poll::Ready(v) => return v,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = 5;
|
||||
assert_eq!(run_fut(foo(&x, 7)), 31);
|
||||
assert_eq!(run_fut(build_aggregate(1, 2, 3, 4)), 10);
|
||||
assert_eq!(run_fut(includes_never(false, 4)), 16);
|
||||
assert_eq!(run_fut(partial_init(4)), 8);
|
||||
run_fut(hello_world());
|
||||
}
|
@ -1,3 +1,7 @@
|
||||
// FIXME(eholk): temporarily disabled while drop range tracking is disabled
|
||||
// (see generator_interior.rs:27)
|
||||
// ignore-test
|
||||
|
||||
#![feature(negative_impls, generators)]
|
||||
|
||||
struct Foo;
|
||||
|
Loading…
x
Reference in New Issue
Block a user