]> git.lizzy.rs Git - rust.git/blob - tests/ui/let-else/let-else-deref-coercion.rs
Don't resolve type var roots in point_at_expr_source_of_inferred_type
[rust.git] / tests / ui / let-else / let-else-deref-coercion.rs
1 // Taken from https://github.com/rust-lang/rust/blob/6cc0a764e082d9c0abcf37a768d5889247ba13e2/compiler/rustc_typeck/src/check/_match.rs#L445-L462
2 //
3 // We attempt to `let Bar::Present(_) = foo else { ... }` where foo is meant to Deref/DerefMut to
4 // Bar. This fails, you must add a type annotation like `let _: &mut Bar = _ else { ... }`
5
6
7 use std::ops::{Deref, DerefMut};
8
9 struct Foo(Bar);
10
11 enum Bar {
12     Present(u32),
13     Absent,
14 }
15 impl Deref for Foo {
16     type Target = Bar;
17     fn deref(&self) -> &Bar {
18         &self.0
19     }
20 }
21 impl DerefMut for Foo {
22     fn deref_mut(&mut self) -> &mut Bar {
23         &mut self.0
24     }
25 }
26 impl Bar {
27     fn bar(&self) -> Option<u32> {
28         let Bar::Present(z): &Bar = self else {
29             return None;
30         };
31         return Some(*z);
32     }
33 }
34 impl Foo {
35     // Try without the type annotation
36     fn set_bar_unannotated(&mut self, value: u32) {
37         let Bar::Present(z) = self else { //~ ERROR mismatched types
38             return;
39         };
40         *z = value;
41     }
42 }
43
44 fn main() {
45     let mut foo = Foo(Bar::Present(1));
46     foo.set_bar_unannotated(54);
47     assert_eq!(foo.bar(), Some(54));
48     irrefutable::inner();
49 }
50
51 // The original, to show it fails for irrefutable let decls
52 mod irrefutable {
53     use std::ops::{Deref, DerefMut};
54     struct Foo(Bar);
55     struct Bar(u32);
56     impl Deref for Foo {
57         type Target = Bar;
58         fn deref(&self) -> &Bar {
59             &self.0
60         }
61     }
62     impl DerefMut for Foo {
63         fn deref_mut(&mut self) -> &mut Bar {
64             &mut self.0
65         }
66     }
67     fn foo(x: &mut Foo) {
68         let Bar(z) = x; //~ ERROR mismatched types
69         *z = 54;
70         assert_eq!((x.0).0, 54);
71     }
72     pub fn inner() {
73         foo(&mut Foo(Bar(1)));
74     }
75 }