| // Test that or-patterns are pass-through with respect to default binding modes. |
| |
| //@ check-pass |
| |
| #![allow(irrefutable_let_patterns)] |
| #![allow(dropping_copy_types)] |
| #![allow(dropping_references)] |
| |
| fn main() { |
| // A regression test for a mistake we made at one point: |
| match &1 { |
| e @ &(1..=2) | e @ &(3..=4) => {} |
| _ => {} |
| } |
| |
| match &0 { |
| 0 | &1 => {} |
| _ => {} |
| } |
| |
| type R<'a> = &'a Result<u8, u8>; |
| |
| let res: R<'_> = &Ok(0); |
| |
| match res { |
| // Alternatives propagate expected type / binding mode independently. |
| Ok(mut x) | &Err(mut x) => drop::<u8>(x), |
| } |
| match res { |
| &(Ok(x) | Err(x)) => drop::<u8>(x), |
| } |
| match res { |
| Ok(x) | Err(x) => drop::<&u8>(x), |
| } |
| if let Ok(mut x) | &Err(mut x) = res { |
| drop::<u8>(x); |
| } |
| if let &(Ok(x) | Err(x)) = res { |
| drop::<u8>(x); |
| } |
| let (Ok(mut x) | &Err(mut x)) = res; |
| drop::<u8>(x); |
| let &(Ok(x) | Err(x)) = res; |
| drop::<u8>(x); |
| let (Ok(x) | Err(x)) = res; |
| drop::<&u8>(x); |
| for Ok(mut x) | &Err(mut x) in std::iter::once(res) { |
| drop::<u8>(x); |
| } |
| for &(Ok(x) | Err(x)) in std::iter::once(res) { |
| drop::<u8>(x); |
| } |
| for Ok(x) | Err(x) in std::iter::once(res) { |
| drop::<&u8>(x); |
| } |
| fn f1((Ok(mut x) | &Err(mut x)): R<'_>) { |
| drop::<u8>(x); |
| } |
| fn f2(&(Ok(x) | Err(x)): R<'_>) { |
| drop::<u8>(x); |
| } |
| fn f3((Ok(x) | Err(x)): R<'_>) { |
| drop::<&u8>(x); |
| } |
| |
| // Wrap inside another type (a product for a simplity with irrefutable contexts). |
| #[derive(Copy, Clone)] |
| struct Wrap<T>(T); |
| let wres = Wrap(res); |
| |
| match wres { |
| Wrap(Ok(mut x) | &Err(mut x)) => drop::<u8>(x), |
| } |
| match wres { |
| Wrap(&(Ok(x) | Err(x))) => drop::<u8>(x), |
| } |
| match wres { |
| Wrap(Ok(x) | Err(x)) => drop::<&u8>(x), |
| } |
| if let Wrap(Ok(mut x) | &Err(mut x)) = wres { |
| drop::<u8>(x); |
| } |
| if let Wrap(&(Ok(x) | Err(x))) = wres { |
| drop::<u8>(x); |
| } |
| if let Wrap(Ok(x) | Err(x)) = wres { |
| drop::<&u8>(x); |
| } |
| let Wrap(Ok(mut x) | &Err(mut x)) = wres; |
| drop::<u8>(x); |
| let Wrap(&(Ok(x) | Err(x))) = wres; |
| drop::<u8>(x); |
| let Wrap(Ok(x) | Err(x)) = wres; |
| drop::<&u8>(x); |
| for Wrap(Ok(mut x) | &Err(mut x)) in std::iter::once(wres) { |
| drop::<u8>(x); |
| } |
| for Wrap(&(Ok(x) | Err(x))) in std::iter::once(wres) { |
| drop::<u8>(x); |
| } |
| for Wrap(Ok(x) | Err(x)) in std::iter::once(wres) { |
| drop::<&u8>(x); |
| } |
| fn fw1(Wrap(Ok(mut x) | &Err(mut x)): Wrap<R<'_>>) { |
| drop::<u8>(x); |
| } |
| fn fw2(Wrap(&(Ok(x) | Err(x))): Wrap<R<'_>>) { |
| drop::<u8>(x); |
| } |
| fn fw3(Wrap(Ok(x) | Err(x)): Wrap<R<'_>>) { |
| drop::<&u8>(x); |
| } |
| |
| // Nest some more: |
| |
| enum Tri<P> { |
| A(P), |
| B(P), |
| C(P), |
| } |
| |
| let tri = &Tri::A(&Ok(0)); |
| let (Tri::A(Ok(mut x) | Err(mut x)) |
| | Tri::B(&Ok(mut x) | Err(mut x)) |
| | &Tri::C(Ok(mut x) | Err(mut x))) = tri; |
| drop::<u8>(x); |
| |
| match tri { |
| Tri::A(Ok(mut x) | Err(mut x)) |
| | Tri::B(&Ok(mut x) | Err(mut x)) |
| | &Tri::C(Ok(mut x) | Err(mut x)) => drop::<u8>(x), |
| } |
| } |