]> git.proxmox.com Git - rustc.git/blob - tests/ui/let-else/let-else-deref-coercion.rs
New upstream version 1.68.2+dfsg1
[rustc.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 }