blob: abed638e44359768af9561eaafc072e81fbb3ac2 [file] [log] [blame]
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
use std::ops::{Coroutine, CoroutineState};
use std::pin::Pin;
fn firstn() -> impl Coroutine<Yield = u64, Return = ()> {
#[coroutine]
static move || {
let mut num = 0;
let num = &mut num;
*num += 0;
yield *num;
*num += 1; //~ERROR: has been freed
}
}
struct CoroutineIteratorAdapter<G>(G);
impl<G> Iterator for CoroutineIteratorAdapter<G>
where
G: Coroutine<Return = ()>,
{
type Item = G::Yield;
fn next(&mut self) -> Option<Self::Item> {
let me = unsafe { Pin::new_unchecked(&mut self.0) };
match me.resume(()) {
CoroutineState::Yielded(x) => Some(x),
CoroutineState::Complete(_) => None,
}
}
}
fn main() {
let mut coroutine_iterator_2 = {
let mut coroutine_iterator = Box::new(CoroutineIteratorAdapter(firstn()));
coroutine_iterator.next(); // pin it
Box::new(*coroutine_iterator) // move it
}; // *deallocate* coroutine_iterator
coroutine_iterator_2.next(); // and use moved value
}