let-else: add deref-coercion tests · rust-lang/rust@fec8a50 (original) (raw)

``

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 {

`

``

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

`+

}

`