let-else: add deref-coercion tests · rust-lang/rust@fec8a50 (original) (raw)
``
1
`+
// check-pass
`
``
2
`+
//
`
``
3
`+
`
``
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 {
`
``
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
`+
}
`