mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-10-31 04:57:19 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			250 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			250 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| //@ run-pass
 | |
| #![allow(unused_variables)]
 | |
| fn some_or_wildcard(r: &Option<i32>, b: &i32) {
 | |
|     let _: &i32 = match r {
 | |
|         Some(a) => a,
 | |
|         _ => b,
 | |
|     };
 | |
| }
 | |
| 
 | |
| fn none_or_wildcard(r: &Option<i32>, b: &i32) {
 | |
|     let _: &i32 = match r {
 | |
|         None => b,
 | |
|         _ => b,
 | |
|     };
 | |
| }
 | |
| 
 | |
| fn some_or_ref_none(r: &Option<i32>, b: &i32) {
 | |
|     let _: &i32 = match r {
 | |
|         Some(a) => a,
 | |
|         &None => b,
 | |
|     };
 | |
| }
 | |
| 
 | |
| fn ref_some_or_none(r: &Option<i32>, b: &i32) {
 | |
|     let _: &i32 = match r {
 | |
|         &Some(ref a) => a,
 | |
|         None => b,
 | |
|     };
 | |
| }
 | |
| 
 | |
| fn some_or_self(r: &Option<i32>) {
 | |
|     let _: &Option<i32> = match r {
 | |
|         Some(n) => {
 | |
|             let _: &i32 = n;
 | |
|             r
 | |
|         },
 | |
|         x => x,
 | |
|     };
 | |
| }
 | |
| 
 | |
| fn multiple_deref(r: &&&&&Option<i32>) {
 | |
|     let _: i32 = match r {
 | |
|         Some(a) => *a,
 | |
|         None => 5,
 | |
|     };
 | |
| }
 | |
| 
 | |
| fn match_with_or() {
 | |
|     // FIXME(tschottdorf): #44912.
 | |
|     //
 | |
|     // let x = &Some((3, 3));
 | |
|     // let _: &i32 = match x {
 | |
|     //     Some((x, 3)) | &Some((ref x, 5)) => x,
 | |
|     //     _ => &5i32,
 | |
|     // };
 | |
| }
 | |
| 
 | |
| fn nested_mixed() {
 | |
|     match (&Some(5), &Some(6)) {
 | |
|         (Some(a), &Some(mut b)) => {
 | |
|             // Here, the `a` will be `&i32`, because in the first half of the tuple
 | |
|             // we hit a non-reference pattern and shift into `ref` mode.
 | |
|             //
 | |
|             // In the second half of the tuple there's no non-reference pattern,
 | |
|             // so `b` will be `i32` (bound with `move` mode). Moreover, `b` is
 | |
|             // mutable.
 | |
|             let _: &i32 = a;
 | |
|             b = 7;
 | |
|             let _: i32 = b;
 | |
|         },
 | |
|         _ => {},
 | |
|     };
 | |
| }
 | |
| 
 | |
| fn nested_mixed_multiple_deref_1() {
 | |
|     let x = (1, &Some(5));
 | |
|     let y = &Some(x);
 | |
|     match y {
 | |
|         Some((a, Some(b))) => {
 | |
|             let _: &i32 = a;
 | |
|             let _: &i32 = b;
 | |
|         },
 | |
|         _ => {},
 | |
|     };
 | |
| }
 | |
| 
 | |
| fn nested_mixed_multiple_deref_2() {
 | |
|     let x = &Some(5);
 | |
|     let y = &x;
 | |
|     match y {
 | |
|         Some(z) => {
 | |
|             let _: &i32 = z;
 | |
|         },
 | |
|         _ => {},
 | |
|     }
 | |
| }
 | |
| 
 | |
| fn new_mutable_reference() {
 | |
|     let mut x = &mut Some(5);
 | |
|     match &mut x {
 | |
|         Some(y) => {
 | |
|             *y = 5;
 | |
|         },
 | |
|         None => { },
 | |
|     }
 | |
| 
 | |
|     match &mut x {
 | |
|         Some(y) => {
 | |
|             println!("{}", *y);
 | |
|         },
 | |
|         None => {},
 | |
|     }
 | |
| }
 | |
| 
 | |
| fn let_implicit_ref_binding() {
 | |
|     struct Foo(i32);
 | |
| 
 | |
|     // Note that these rules apply to any pattern matching
 | |
|     // whether it be in a `match` or a `let`.
 | |
|     // For example, `x` here is a `ref` binding:
 | |
|     let Foo(x) = &Foo(3);
 | |
|     let _: &i32 = x;
 | |
| }
 | |
| 
 | |
| fn explicit_mut_binding() {
 | |
|     match &Some(5i32) {
 | |
|         Some(mut n) => {
 | |
|             n += 1;
 | |
|             let _ = n;
 | |
|         }
 | |
|         None => {},
 | |
|     };
 | |
| 
 | |
|     match &mut Some(5i32) {
 | |
|         Some(n) => {
 | |
|             *n += 1;
 | |
|             let _ = n;
 | |
|         }
 | |
|         None => {},
 | |
|     };
 | |
| 
 | |
|     match &mut &mut Some(5i32) {
 | |
|         Some(n) => {
 | |
|              let _: &mut i32 = n;
 | |
|         }
 | |
|         None => {},
 | |
|     };
 | |
| }
 | |
| 
 | |
| fn tuple_mut_and_mut_mut() {
 | |
|     match (Some(5i32), &Some(5i32)) {
 | |
|         (Some(n), Some(m)) => {
 | |
|             // `n` and `m` are bound as immutable references. Make new references from them to
 | |
|             // assert that.
 | |
|             let r = n;
 | |
|             let _ = r;
 | |
|             let q = m;
 | |
|             let _ = q;
 | |
| 
 | |
|             // Assert the types. Note that we use `n` and `m` here which would fail had they been
 | |
|             // moved due to the assignments above.
 | |
|             let _: i32 = n;
 | |
|             let _: &i32 = m;
 | |
|         }
 | |
|         (_, _) => {},
 | |
|     };
 | |
| 
 | |
|     match (&Some(5i32), &&Some(5i32)) {
 | |
|         (Some(n), Some(m)) => {
 | |
|             let _: &i32 = n;
 | |
|             let _: &i32 = m;
 | |
|         }
 | |
|         (_, _) => {},
 | |
|     };
 | |
| 
 | |
|     match &mut &mut (Some(5i32), Some(5i32)) {
 | |
|         (Some(n), Some(m)) => {
 | |
|             // Dereferenced through &mut &mut, so a mutable binding results.
 | |
|             let _: &mut i32 = n;
 | |
|             let _: &mut i32 = m;
 | |
|         }
 | |
|         (_, _) => {},
 | |
|     };
 | |
| 
 | |
|     match (&mut Some(5i32), &mut &mut Some(5i32)) {
 | |
|         (Some(n), Some(m)) => {
 | |
|             let _: &mut i32 = n;
 | |
|             let _: &mut i32 = m;
 | |
|         }
 | |
|         (_, _) => {},
 | |
|     };
 | |
| }
 | |
| 
 | |
| fn min_mir_embedded_type() {
 | |
|     // The reduced invocation that an ICE was diagnosed with (was consuming
 | |
|     // adjustments in wrong order).
 | |
|     match (0u8, &&Some(5i32)) {
 | |
|         (_, Some(m)) => {
 | |
|             let _: &i32 = m;
 | |
|         }
 | |
|         (_, _) => {},
 | |
|     };
 | |
| }
 | |
| 
 | |
| fn no_autoderef() {
 | |
|     // Binding.
 | |
|     let x = &3;
 | |
|     println!("{}", *x);
 | |
| 
 | |
|     // Wildcard.
 | |
|     let _ = &3;
 | |
| 
 | |
|     // Constant of generic type (string)
 | |
|     const Y: &'static str = "foo";
 | |
|     assert_eq!(0, match "foo" {
 | |
|         Y => 0,
 | |
|         _ => 1,
 | |
|     });
 | |
| 
 | |
|     // Reference pattern.
 | |
|     let &x = &3;
 | |
| }
 | |
| 
 | |
| pub fn main() {
 | |
|     let r: &Option<i32> = &Some(3);
 | |
|     let b = &4i32;
 | |
| 
 | |
|     none_or_wildcard(r, b);
 | |
|     some_or_wildcard(r, b);
 | |
|     some_or_ref_none(r, b);
 | |
|     ref_some_or_none(r, b);
 | |
| 
 | |
|     some_or_self(r);
 | |
|     multiple_deref(&&&&r);
 | |
|     match_with_or();
 | |
| 
 | |
|     nested_mixed();
 | |
|     nested_mixed_multiple_deref_1();
 | |
|     nested_mixed_multiple_deref_2();
 | |
| 
 | |
|     new_mutable_reference();
 | |
|     explicit_mut_binding();
 | |
|     tuple_mut_and_mut_mut();
 | |
|     min_mir_embedded_type();
 | |
| 
 | |
|     let_implicit_ref_binding();
 | |
| 
 | |
|     no_autoderef();
 | |
| }
 | 
