mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-10-31 04:57:19 +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);
 | |
| }
 | 
