mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-11-04 06:56:14 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			139 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
//@ build-pass
 | 
						|
 | 
						|
// A test to ensure coroutines 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 coroutine type.
 | 
						|
 | 
						|
#![feature(coroutines, negative_impls, stmt_expr_attributes)]
 | 
						|
#![allow(unused_assignments, dead_code)]
 | 
						|
 | 
						|
struct Ptr;
 | 
						|
impl<'a> Drop for Ptr {
 | 
						|
    fn drop(&mut self) {}
 | 
						|
}
 | 
						|
 | 
						|
struct NonSend;
 | 
						|
impl !Send for NonSend {}
 | 
						|
 | 
						|
fn assert_send<T: Send>(_: T) {}
 | 
						|
 | 
						|
// This test case is reduced from tests/ui/drop/dynamic-drop-async.rs
 | 
						|
fn one_armed_if(arg: bool) {
 | 
						|
    let _ = #[coroutine] || {
 | 
						|
        let arr = [Ptr];
 | 
						|
        if arg {
 | 
						|
            drop(arr);
 | 
						|
        }
 | 
						|
        yield;
 | 
						|
    };
 | 
						|
}
 | 
						|
 | 
						|
fn two_armed_if(arg: bool) {
 | 
						|
    assert_send(#[coroutine] || {
 | 
						|
        let arr = [Ptr];
 | 
						|
        if arg {
 | 
						|
            drop(arr);
 | 
						|
        } else {
 | 
						|
            drop(arr);
 | 
						|
        }
 | 
						|
        yield;
 | 
						|
    })
 | 
						|
}
 | 
						|
 | 
						|
fn if_let(arg: Option<i32>) {
 | 
						|
    let _ = #[coroutine] || {
 | 
						|
        let arr = [Ptr];
 | 
						|
        if let Some(_) = arg {
 | 
						|
            drop(arr);
 | 
						|
        }
 | 
						|
        yield;
 | 
						|
    };
 | 
						|
}
 | 
						|
 | 
						|
fn init_in_if(arg: bool) {
 | 
						|
    assert_send(#[coroutine] || {
 | 
						|
        let mut x = NonSend;
 | 
						|
        drop(x);
 | 
						|
        if arg {
 | 
						|
            x = NonSend;
 | 
						|
        } else {
 | 
						|
            yield;
 | 
						|
        }
 | 
						|
    })
 | 
						|
}
 | 
						|
 | 
						|
fn init_in_match_arm(arg: Option<i32>) {
 | 
						|
    assert_send(#[coroutine] || {
 | 
						|
        let mut x = NonSend;
 | 
						|
        drop(x);
 | 
						|
        match arg {
 | 
						|
            Some(_) => x = NonSend,
 | 
						|
            None => yield,
 | 
						|
        }
 | 
						|
    })
 | 
						|
}
 | 
						|
 | 
						|
fn reinit() {
 | 
						|
    let _ = #[coroutine] || {
 | 
						|
        let mut arr = [Ptr];
 | 
						|
        drop(arr);
 | 
						|
        arr = [Ptr];
 | 
						|
        yield;
 | 
						|
    };
 | 
						|
}
 | 
						|
 | 
						|
fn loop_uninit() {
 | 
						|
    let _ = #[coroutine] || {
 | 
						|
        let mut arr = [Ptr];
 | 
						|
        let mut count = 0;
 | 
						|
        drop(arr);
 | 
						|
        while count < 3 {
 | 
						|
            yield;
 | 
						|
            arr = [Ptr];
 | 
						|
            count += 1;
 | 
						|
        }
 | 
						|
    };
 | 
						|
}
 | 
						|
 | 
						|
fn nested_loop() {
 | 
						|
    let _ = #[coroutine] || {
 | 
						|
        let mut arr = [Ptr];
 | 
						|
        let mut count = 0;
 | 
						|
        drop(arr);
 | 
						|
        while count < 3 {
 | 
						|
            for _ in 0..3 {
 | 
						|
                yield;
 | 
						|
            }
 | 
						|
            arr = [Ptr];
 | 
						|
            count += 1;
 | 
						|
        }
 | 
						|
    };
 | 
						|
}
 | 
						|
 | 
						|
fn loop_continue(b: bool) {
 | 
						|
    let _ = #[coroutine] || {
 | 
						|
        let mut arr = [Ptr];
 | 
						|
        let mut count = 0;
 | 
						|
        drop(arr);
 | 
						|
        while count < 3 {
 | 
						|
            count += 1;
 | 
						|
            yield;
 | 
						|
            if b {
 | 
						|
                arr = [Ptr];
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    };
 | 
						|
}
 | 
						|
 | 
						|
fn main() {
 | 
						|
    one_armed_if(true);
 | 
						|
    if_let(Some(41));
 | 
						|
    init_in_if(true);
 | 
						|
    init_in_match_arm(Some(41));
 | 
						|
    reinit();
 | 
						|
    loop_uninit();
 | 
						|
    nested_loop();
 | 
						|
    loop_continue(true);
 | 
						|
}
 |