]> git.lizzy.rs Git - rust.git/blob - src/test/ui/let-else/let-else-deref-coercion-annotated.rs
Auto merge of #93718 - thomcc:used-macho, r=pnkfelix
[rust.git] / src / test / ui / let-else / let-else-deref-coercion-annotated.rs
1 // check-pass
2 //
3 // Taken from https://github.com/rust-lang/rust/blob/6cc0a764e082d9c0abcf37a768d5889247ba13e2/compiler/rustc_typeck/src/check/_match.rs#L445-L462
4 //
5 // We attempt to `let Bar::Present(_): &mut Bar = foo else { ... }` where foo is meant to
6 // Deref/DerefMut to Bar. You can do this with an irrefutable binding, so it should work with
7 // let-else too.
8
9 #![feature(let_else)]
10 use std::ops::{Deref, DerefMut};
11
12 struct Foo(Bar);
13
14 enum Bar {
15     Present(u32),
16     Absent,
17 }
18 impl Deref for Foo {
19     type Target = Bar;
20     fn deref(&self) -> &Bar {
21         &self.0
22     }
23 }
24 impl DerefMut for Foo {
25     fn deref_mut(&mut self) -> &mut Bar {
26         &mut self.0
27     }
28 }
29 impl Bar {
30     fn bar(&self) -> Option<u32> {
31         let Bar::Present(z): &Bar = self else {
32             return None;
33         };
34         return Some(*z);
35     }
36 }
37 impl Foo {
38     fn set_bar_annotated(&mut self, value: u32) {
39         let Bar::Present(z): &mut Bar = self else { // OK
40             return;
41         };
42         *z = value;
43     }
44 }
45
46 fn main() {
47     let mut foo = Foo(Bar::Present(1));
48     foo.set_bar_annotated(42);
49     assert_eq!(foo.bar(), Some(42));
50     irrefutable::inner();
51 }
52
53 // The original, to show it works for irrefutable let decls
54 mod irrefutable {
55     use std::ops::{Deref, DerefMut};
56     struct Foo(Bar);
57     struct Bar(u32);
58     impl Deref for Foo {
59         type Target = Bar;
60         fn deref(&self) -> &Bar {
61             &self.0
62         }
63     }
64     impl DerefMut for Foo {
65         fn deref_mut(&mut self) -> &mut Bar {
66             &mut self.0
67         }
68     }
69     fn foo(x: &mut Foo) {
70         let Bar(z): &mut Bar = x; // OK
71         *z = 42;
72         assert_eq!((x.0).0, 42);
73     }
74     pub fn inner() {
75         foo(&mut Foo(Bar(1)));
76     }
77 }