// run-pass #![allow(unused_variables)] fn some_or_wildcard(r: &Option, b: &i32) { let _: &i32 = match r { Some(a) => a, _ => b, }; } fn none_or_wildcard(r: &Option, b: &i32) { let _: &i32 = match r { None => b, _ => b, }; } fn some_or_ref_none(r: &Option, b: &i32) { let _: &i32 = match r { Some(a) => a, &None => b, }; } fn ref_some_or_none(r: &Option, b: &i32) { let _: &i32 = match r { &Some(ref a) => a, None => b, }; } fn some_or_self(r: &Option) { let _: &Option = match r { Some(n) => { let _: &i32 = n; r }, x => x, }; } fn multiple_deref(r: &&&&&Option) { 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 = &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(); }